Skip to content

feat(MSDK-3794): Add Firebase mediation integration to React Native sample app#210

Open
asadraza-usercentrics wants to merge 4 commits intomasterfrom
feat/MSDK-3794-firebase-mediation-sample
Open

feat(MSDK-3794): Add Firebase mediation integration to React Native sample app#210
asadraza-usercentrics wants to merge 4 commits intomasterfrom
feat/MSDK-3794-firebase-mediation-sample

Conversation

@asadraza-usercentrics
Copy link
Copy Markdown
Contributor

@asadraza-usercentrics asadraza-usercentrics commented May 8, 2026

User description

PR description

Summary

  • Moves Usercentrics.configure() into App.tsx via useEffect with
    MEDIATION_TEST_ENABLED and SETTINGS_ID as the single control point for
    mediation mode and settings configuration
  • Adds auto Usercentrics.status() check on HomeScreen mount — shows first
    layer immediately if consent is required, otherwise applies existing consents
  • Integrates Firebase Analytics as a reference mediation partner on both platforms:
    • Android: google-services plugin, Firebase BOM 33.13.0, all collection
      flags disabled by default in AndroidManifest.xml
    • iOS: FirebaseAnalytics pod, FirebaseApp.configure() in AppDelegate,
      FIREBASE_ANALYTICS_COLLECTION_ENABLED = false in Info.plist,
      PrivacyInfo.xcprivacy updated with NSUserDefaults access reasons
  • Updates bundle/application ID to com.usercentrics.sdk.mediation.test on
    both platforms
  • Rewrites sample/README.md — replaces the default RN boilerplate with a
    full guide covering prerequisites, project structure, screen descriptions,
    run instructions, consent mediation setup, New Architecture toggle,
    scripts reference, and troubleshooting

Summary by CodeRabbit

  • Documentation

    • Comprehensive README with platform-specific prerequisites, project structure, SDK initialization guidance, step-by-step setup instructions, consent flow walkthrough, and expanded troubleshooting.
  • New Features

    • Firebase Analytics integration and mediation testing capability in the sample app.
    • Enhanced consent flow handling with automatic first-layer display and consent status checks.
  • Chores

    • Android and iOS platform configuration updates; Firebase configuration files added to .gitignore.

CodeAnt-AI Description

Add Firebase consent mediation to the sample app and refresh the usage guide

What Changed

  • The sample app now includes Firebase Analytics as a mediation partner on both Android and iOS, with collection turned off until consent is granted
  • App startup now uses one settings point for mediation testing, and the home screen checks consent automatically on launch to show the banner or apply saved choices
  • The sample app now uses a new test app identifier and includes the Firebase config file needed for iOS
  • The README was rewritten with setup steps, screen walkthroughs, mediation testing instructions, and troubleshooting notes

Impact

✅ Consent can be tested with Firebase in the sample app
✅ Fewer manual steps to start the consent flow
✅ Clearer setup and testing instructions for the sample app

🔄 Retrigger CodeAnt AI Review

Details

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack

Warning

Rate limit exceeded

@asadraza-usercentrics has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 4 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 03b633c4-dee5-4fc4-8a2a-e5595f9b15de

📥 Commits

Reviewing files that changed from the base of the PR and between c51e619 and 9f8364c.

📒 Files selected for processing (3)
  • sample/android/app/build.gradle.kts
  • sample/ios/sample.xcodeproj/project.pbxproj
  • sample/ios/sample/AppDelegate.swift
📝 Walkthrough

Walkthrough

This PR equips the Usercentrics React Native SDK sample app with Firebase Analytics integration and consent mediation capabilities. Android and iOS build configurations add Google Services plugins and Firebase dependencies. The Usercentrics SDK is initialized with a mediation flag and debug logging. The Home screen checks consent status at mount time, displays consent layers, and handles responses. Comprehensive documentation covers platform-specific setup, mediation testing, and troubleshooting.

Changes

Firebase Integration and Consent Mediation

Layer / File(s) Summary
Bundle Identifier Configuration
sample/android/app/build.gradle.kts, sample/ios/sample.xcodeproj/project.pbxproj
Both Android and iOS targets update bundle identifier to com.usercentrics.sdk.mediation.test. Xcode project references and includes GoogleService-Info.plist in build resources.
Android Build Dependencies and Plugins
sample/android/build.gradle.kts, sample/android/app/build.gradle.kts, sample/android/settings.gradle.kts, sample/android/app/src/main/AndroidManifest.xml
Google Services Gradle plugin added to root buildscript, Firebase BoM and Analytics library added to app dependencies, mavenLocal() added for dependency resolution, AndroidManifest metadata entries disable Firebase Analytics collection.
iOS Pods and Runtime Configuration
sample/ios/Podfile, sample/ios/sample/AppDelegate.swift, sample/ios/sample/Info.plist, sample/ios/sample/PrivacyInfo.xcprivacy
FirebaseAnalytics pod added to sample target, AppDelegate imports FirebaseCore and calls FirebaseApp.configure() at app launch, Info.plist disables analytics collection, PrivacyInfo.xcprivacy declares additional API access reasons for UserDefaults and FileTimestamp.
Usercentrics SDK Initialization
sample/src/App.tsx
SDK configure() call updated to include settingsId, loggerLevel: debug, and consentMediation flag driven by MEDIATION_TEST_ENABLED constant.
Consent Flow Integration
sample/src/screens/Home.tsx
HomeScreen mounts with status check, conditionally shows first layer or applies existing consent, introduces handleUserResponse for logging and consent application, updates showFirstLayer() and showSecondLayer() to await layer display and route responses, rewrites A/B testing banner helpers with BannerSettings casting, adjusts button callbacks for consent interactions.
Documentation and Configuration
sample/.gitignore, sample/README.md
.gitignore ignores Firebase config files (google-services.json, GoogleService-Info.plist). README fully replaced with comprehensive guide covering prerequisites, SDK initialization, platform-specific running instructions, screen guide, Firebase mediation setup with testing steps, New Architecture toggles, available npm scripts, and troubleshooting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Usercentrics/react-native-sdk#184: Both PRs modify the sample app's native project configuration (iOS Podfile/Info.plist/Xcode project and Android Gradle settings) to align the sample with SDK/release requirements (e.g., RN new-arch toggles, Podfile/Gradle changes, sample bundle IDs and Firebase setup).

Suggested labels

Review effort 2/5

Suggested reviewers

  • uc-brunosilva
  • islameldesoky95
  • uc-brunosouza

Poem

🐰 Firebase flames ignite the night,
Consent flows gather, burning bright!
Mediation blooms in Android soil,
While iOS gently tends the toil—
A sample app now stands complete! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: adding Firebase mediation integration to the React Native sample app, which is reflected across all file modifications (Firebase dependencies, configuration, SDK setup).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/MSDK-3794-firebase-mediation-sample

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add Firebase mediation integration and comprehensive documentation to React Native sample app

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Integrates Firebase Analytics as mediation partner on Android and iOS
• Moves SDK configuration to App.tsx with mediation mode toggle flag
• Adds automatic consent status check on HomeScreen mount
• Updates bundle ID to com.usercentrics.sdk.mediation.test
• Completely rewrites README with comprehensive setup and usage guide
Diagram
flowchart LR
  A["App.tsx<br/>SDK Config"] -->|"MEDIATION_TEST_ENABLED"| B["Firebase<br/>Integration"]
  A -->|"SETTINGS_ID"| C["Usercentrics<br/>Configuration"]
  D["HomeScreen"] -->|"useEffect"| E["Usercentrics.status()"]
  E -->|"shouldCollectConsent"| F["Show Banner"]
  E -->|"existing consents"| G["Apply Consent"]
  H["Android Setup<br/>google-services plugin"] --> B
  I["iOS Setup<br/>FirebaseApp.configure"] --> B
  B -->|"mediation"| J["Consent Propagation"]
Loading

Grey Divider

File Changes

1. sample/android/app/build.gradle.kts Dependencies +6/-1

Add Firebase BOM and google-services plugin

sample/android/app/build.gradle.kts


2. sample/android/build.gradle.kts Dependencies +1/-0

Add google-services classpath dependency

sample/android/build.gradle.kts


3. sample/android/settings.gradle.kts ⚙️ Configuration changes +1/-0

Add mavenLocal repository for local dependencies

sample/android/settings.gradle.kts


View more (10)
4. sample/android/app/src/main/AndroidManifest.xml ⚙️ Configuration changes +6/-0

Disable Firebase analytics collection by default

sample/android/app/src/main/AndroidManifest.xml


5. sample/ios/sample/AppDelegate.swift ✨ Enhancement +2/-0

Import FirebaseCore and initialize Firebase

sample/ios/sample/AppDelegate.swift


6. sample/ios/Podfile Dependencies +2/-0

Add FirebaseAnalytics pod dependency

sample/ios/Podfile


7. sample/ios/sample.xcodeproj/project.pbxproj ⚙️ Configuration changes +6/-2

Add GoogleService-Info.plist build resource

sample/ios/sample.xcodeproj/project.pbxproj


8. sample/ios/sample/GoogleService-Info.plist ⚙️ Configuration changes +32/-0

Add Firebase configuration file for iOS

sample/ios/sample/GoogleService-Info.plist


9. sample/ios/sample/Info.plist ⚙️ Configuration changes +2/-0

Disable Firebase analytics collection flag

sample/ios/sample/Info.plist


10. sample/ios/sample/PrivacyInfo.xcprivacy ⚙️ Configuration changes +6/-4

Update privacy manifest with NSUserDefaults access

sample/ios/sample/PrivacyInfo.xcprivacy


11. sample/src/App.tsx ✨ Enhancement +25/-26

Add mediation test flag and SDK configuration

sample/src/App.tsx


12. sample/src/screens/Home.tsx ✨ Enhancement +66/-75

Add automatic status check and consent handling

sample/src/screens/Home.tsx


13. sample/README.md 📝 Documentation +297/-50

Replace boilerplate with comprehensive integration guide

sample/README.md


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 8, 2026

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Firebase plist committed ✓ Resolved 🐞 Bug ⛨ Security
Description
The PR adds and bundles GoogleService-Info.plist containing a Firebase API key and project
identifiers, while the README states Firebase config files are not committed. This leaks shared
Firebase project configuration and can lead to unintended reuse/abuse of that Firebase project from
a public repo.
Code

sample/ios/sample/GoogleService-Info.plist[R1-32]

+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>API_KEY</key>
+	<string>AIzaSyCbVPJwkNblldnnC6drkANOFNBR0pc16vc</string>
+	<key>GCM_SENDER_ID</key>
+	<string>562107654987</string>
+	<key>PLIST_VERSION</key>
+	<string>1</string>
+	<key>BUNDLE_ID</key>
+	<string>com.usercentrics.sdk.mediation.test</string>
+	<key>PROJECT_ID</key>
+	<string>in-app-sdk</string>
+	<key>STORAGE_BUCKET</key>
+	<string>in-app-sdk.firebasestorage.app</string>
+	<key>IS_ADS_ENABLED</key>
+	<false></false>
+	<key>IS_ANALYTICS_ENABLED</key>
+	<false></false>
+	<key>IS_APPINVITE_ENABLED</key>
+	<true></true>
+	<key>IS_GCM_ENABLED</key>
+	<true></true>
+	<key>IS_SIGNIN_ENABLED</key>
+	<true></true>
+	<key>GOOGLE_APP_ID</key>
+	<string>1:562107654987:ios:582fcab0c3093857befece</string>
+	<key>DATABASE_URL</key>
+	<string>https://in-app-sdk.firebaseio.com</string>
+</dict>
+</plist>
Evidence
The added plist contains Firebase credentials/config values (API key, sender id, project id) and the
Xcode project includes it as a build resource; meanwhile the sample README explicitly claims these
config files are not committed.

sample/ios/sample/GoogleService-Info.plist[1-32]
sample/ios/sample.xcodeproj/project.pbxproj[9-16]
sample/ios/sample.xcodeproj/project.pbxproj[29-46]
sample/README.md[251-260]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`sample/ios/sample/GoogleService-Info.plist` is committed and bundled, and it contains real Firebase project configuration (API key / IDs). This contradicts the README (“not committed”) and is a security anti-pattern for a public sample.
### Issue Context
If CI needs a plist to build tests, don’t commit real project credentials. Prefer a placeholder/template file and require developers to supply their own, or inject via CI secrets/artifacts.
### Fix Focus Areas
- sample/ios/sample/GoogleService-Info.plist[1-32]
- sample/ios/sample.xcodeproj/project.pbxproj[9-16]
- sample/ios/sample.xcodeproj/project.pbxproj[29-46]
- sample/README.md[251-260]
### Suggested fix
- Remove `GoogleService-Info.plist` from git (and from Xcode “Resources”) and add it to an ignore list.
- Alternatively, keep a `GoogleService-Info.plist.example` with scrubbed/dummy values and update the build to copy/rename it locally.
- If the app must run without the plist, guard `FirebaseApp.configure()` (e.g., only call it if the plist exists and Firebase isn’t already configured).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Consent apply is no-op 🐞 Bug ≡ Correctness
Description
HomeScreen calls applyConsent(status.consents) on mount and after user interaction, but
applyConsent is an empty stub. As a result, existing consents and user decisions are never
applied/propagated from the Home screen flow.
Code

sample/src/screens/Home.tsx[R41-43]

+    function applyConsent(_consents?: UsercentricsServiceConsent[] | null) {
+        // https://docs.usercentrics.com/cmp_in_app_sdk/latest/apply_consent/apply-consent/#apply-consent-to-each-service
+    }
Evidence
applyConsent(...) is invoked from the startup status check and after banner responses, but the
function body is empty. The codebase already shows an example implementation pattern in
CustomUI.tsx (iterating/logging consents), demonstrating the intended behavior for
applying/handling consents.

sample/src/screens/Home.tsx[12-19]
sample/src/screens/Home.tsx[34-43]
sample/src/screens/CustomUI.tsx[297-302]
sample/README.md[156-160]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`HomeScreen.applyConsent(...)` is currently a no-op, but it’s called when `shouldCollectConsent` is false and after `showFirstLayer/showSecondLayer` responses. This means the Home screen flow never applies/handles the consents it retrieves.
### Issue Context
The sample already contains an `applyConsents(...)` implementation pattern in `CustomUI.tsx` (iterating consents and logging). The Home screen should do something equivalent (at minimum) and/or trigger partner updates if that’s the point of the mediation demo.
### Fix Focus Areas
- sample/src/screens/Home.tsx[12-19]
- sample/src/screens/Home.tsx[34-43]
- sample/src/screens/CustomUI.tsx[297-302]
### Suggested fix
- Implement `applyConsent` to process the provided `UsercentricsServiceConsent[]`:
- At minimum: iterate and log `templateId/status/type` (like `CustomUI.tsx`).
- If the sample intends to demonstrate partner enable/disable: route consent state to the relevant SDK(s) (or explicitly note that mediation handles it and remove the misleading calls/README text).
- Ensure `applyConsent(undefined/null)` is handled safely (early return).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Unhandled status rejection 🐞 Bug ☼ Reliability
Description
HomeScreen starts Usercentrics.status().then(...) on mount without a .catch(), and it calls
the async showFirstLayer() without awaiting or error handling. Since status()/showFirstLayer()
can reject when native isReady fails, this can produce unhandled promise rejections and a broken
launch flow.
Code

sample/src/screens/Home.tsx[R12-19]

+    React.useEffect(() => {
+        Usercentrics.status().then(status => {
+            if (status.shouldCollectConsent) {
+                showFirstLayer();
+            } else {
+                applyConsent(status.consents);
+            }
+        });
Evidence
The JS SDK’s status() maps directly to the native isReady() promise; the iOS native module
explicitly rejects on failure. The Home screen does not catch these failures, and it fires
showFirstLayer() without awaiting, so any thrown error becomes unhandled.

sample/src/screens/Home.tsx[12-19]
src/Usercentrics.tsx[34-46]
ios/RNUsercentricsModule.swift[61-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Home screen’s startup effect doesn’t handle promise rejections from `Usercentrics.status()` and doesn’t await/catch `showFirstLayer()`. Failures can surface as unhandled promise rejections.
### Issue Context
`Usercentrics.status()` delegates to native `isReady()`, which can reject (e.g., initialization/config issues). `showFirstLayer()` awaits `isReady()` internally and can also throw.
### Fix Focus Areas
- sample/src/screens/Home.tsx[12-19]
- src/Usercentrics.tsx[34-46]
- ios/RNUsercentricsModule.swift[61-70]
### Suggested fix
- Convert the effect to an async IIFE with `try/catch` and await the async calls:
- `const run = async () => { try { const status = await Usercentrics.status(); ... await showFirstLayer(); } catch (e) { console.warn(...); } }`.
- Optionally add an `isMounted` flag in the effect cleanup to avoid acting after unmount.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. mavenLocal precedence 🐞 Bug ⛨ Security
Description
sample/android/settings.gradle.kts adds mavenLocal() before google()/mavenCentral(), which
can silently shadow real dependencies with locally published artifacts. This makes builds
non-reproducible and increases supply-chain risk on developer machines.
Code

sample/android/settings.gradle.kts[R18-21]

+        mavenLocal()
      google()
      mavenCentral()
      maven { url = uri("$rootDir/../node_modules/@react-native/gradle-plugin") }
Evidence
Gradle will consult mavenLocal() first given the repository ordering in the PR, so any locally
published group/artifact/version can override remote artifacts without any code change.

sample/android/settings.gradle.kts[15-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The sample’s Gradle settings now prefer `mavenLocal()` ahead of `google()` and `mavenCentral()`, which can cause dependency shadowing and non-reproducible builds.
### Issue Context
For sample apps (and especially CI), deterministic dependency resolution is typically preferred.
### Fix Focus Areas
- sample/android/settings.gradle.kts[15-23]
### Suggested fix
- Remove `mavenLocal()` entirely, or move it to the end of the repositories list.
- If it’s only needed for local development, gate it behind a Gradle property (e.g., `-PuseMavenLocal=true`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

5. Mediation enabled by default 🐞 Bug ⚙ Maintainability
Description
MEDIATION_TEST_ENABLED is set to true even though the inline comment says to keep it false for
normal builds. This makes the sample default behavior inconsistent and can surprise users who run
the sample without intending to test mediation.
Code

sample/src/App.tsx[R7-9]

+// Set to true when testing consent mediation. Keep false for normal builds.
+const MEDIATION_TEST_ENABLED = true;
+const SETTINGS_ID = '3C9-yvno8-dEzy';
Evidence
The constant is hard-coded to true while the accompanying comment instructs the opposite, so the
code and documentation are out of sync at the primary control point for mediation mode.

sample/src/App.tsx[7-19]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`MEDIATION_TEST_ENABLED` is hard-coded to `true` but commented as something to keep `false` for normal builds, which is inconsistent and confusing.
### Issue Context
This is the “single control point” for mediation mode per the README.
### Fix Focus Areas
- sample/src/App.tsx[7-19]
### Suggested fix
- Set `MEDIATION_TEST_ENABLED` default to `false` and update README steps to instruct toggling it to `true` when testing mediation (or adjust the comment/README to match the intended default).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@pantoaibot
Copy link
Copy Markdown

pantoaibot Bot commented May 8, 2026

PR Summary:

Adds Firebase consent-mediation to the React Native sample app: integrates Firebase Analytics as a mediation partner, wires native Firebase setup, enables consent mediation in the JS SDK, and updates docs and sample flows.

Key changes:

  • Documentation
    • Rewrote sample/README.md to document Firebase mediation, init steps, running instructions, mediation testing, Firebase config locations, and new-architecture notes.
  • Android (sample/android/)
    • Enabled Google Services plugin (com.google.gms.google-services) in app plugins and buildscript classpath.
    • Added Firebase BOM (33.13.0) and firebase-analytics dependency.
    • Added Firebase collection meta-data flags (all false) to AndroidManifest.xml.
    • Changed applicationId to com.usercentrics.sdk.mediation.test.
    • Added mavenLocal() to settings repositories.
  • iOS (sample/ios/)
    • Added pod 'FirebaseAnalytics' to Podfile.
    • AppDelegate.swift imports FirebaseCore and calls FirebaseApp.configure().
    • Info.plist sets FIREBASE_ANALYTICS_COLLECTION_ENABLED = false.
    • PrivacyInfo.xcprivacy updated with UserDefaults/privacy reasons required by Firebase.
    • Xcode project updated to include GoogleService-Info.plist and bundle identifier changed to com.usercentrics.sdk.mediation.test.
    • Added sample/GoogleService-Info.plist (contains Firebase config for sample project).
  • JavaScript / TypeScript (sample/src/)
    • App.tsx: initializes Usercentrics with settingsId, debug logger and consentMediation enabled (MEDIATION_TEST_ENABLED = true).
    • Home.tsx: refactored to use typed SDK imports, auto-check Usercentrics.status() on mount (show first layer or apply consents), unified response handling, added applyConsent stub, A/B testing examples cleaned up, UI button handlers simplified.
  • Build & tooling
    • Gradle/Kotlin DSL changes require updated Gradle plugins and may need npx pod-install / Gradle sync.

Potential breaking / noteworthy items:

  • Bundle ID / applicationId changed for both platforms (com.usercentrics.sdk.mediation.test) — existing installs will be treated as a different app; Firebase config must match the new bundle/application id.
  • GoogleService-Info.plist was added to repo (contains API key) while README still notes config files are not committed — check intended handling of credentials.
  • settings.gradle.kts now includes mavenLocal(); build environment may resolve different artifacts from local repo.
  • Sample now enables consent mediation by default (MEDIATION_TEST_ENABLED = true) — toggle off in src/App.tsx for normal sample behavior.

Reviewed by Panto AI

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label May 8, 2026
Comment on lines +5 to +6
<key>API_KEY</key>
<string>AIzaSyCbVPJwkNblldnnC6drkANOFNBR0pc16vc</string>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The Firebase API_KEY is committed directly in the repository, which is a credential exposure risk and can be abused if key restrictions are relaxed or misconfigured. Move this value out of source control (for example via per-environment config injection in CI/local secrets) and keep only a template file in git. [security]

Severity Level: Critical 🚨
- ❌ Firebase project API key exposed in repository history.
- ⚠️ Sample iOS app always ships same Firebase credentials.
- ⚠️ Misconfigured key restrictions enable potential project abuse.
Steps of Reproduction ✅
1. Clone the repository containing this PR and open
`sample/ios/sample/GoogleService-Info.plist`.

2. Inspect lines 5-6 in `sample/ios/sample/GoogleService-Info.plist`, where
`<key>API_KEY</key>` is followed by the hardcoded Firebase key
`AIzaSyCbVPJwkNblldnnC6drkANOFNBR0pc16vc`.

3. Open `sample/ios/sample.xcodeproj/project.pbxproj` and observe the
PBXBuildFile/PBXFileReference entries at lines 15 and 42 referencing
`GoogleService-Info.plist` as a resource with path `sample/GoogleService-Info.plist`,
confirming it is bundled with the iOS sample app.

4. Any time this repository is shared (e.g., pushed to a remote, mirrored, or downloaded),
the Firebase API key in `GoogleService-Info.plist` is exposed and can be abused if
project-level key restrictions in the Firebase/Google Cloud console are missing or
misconfigured.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** sample/ios/sample/GoogleService-Info.plist
**Line:** 5:6
**Comment:**
	*Security: The Firebase `API_KEY` is committed directly in the repository, which is a credential exposure risk and can be abused if key restrictions are relaxed or misconfigured. Move this value out of source control (for example via per-environment config injection in CI/local secrets) and keep only a template file in git.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +1 to +32
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>API_KEY</key>
<string>AIzaSyCbVPJwkNblldnnC6drkANOFNBR0pc16vc</string>
<key>GCM_SENDER_ID</key>
<string>562107654987</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.usercentrics.sdk.mediation.test</string>
<key>PROJECT_ID</key>
<string>in-app-sdk</string>
<key>STORAGE_BUCKET</key>
<string>in-app-sdk.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:562107654987:ios:582fcab0c3093857befece</string>
<key>DATABASE_URL</key>
<string>https://in-app-sdk.firebaseio.com</string>
</dict>
</plist> No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CRITICAL_BUG] This file contains live Firebase configuration values (API_KEY, GOOGLE_APP_ID, PROJECT_ID, sender IDs) and was committed into the repo. That leaks credentials and violates the README promise that platform config files are NOT committed. Remove this file from the repository immediately, rotate any exposed keys if they are real, and add a placeholder (or example.template) file instead. Update .gitignore and README to document where to place the real GoogleService-Info.plist (not committed).

<!-- Remove real GoogleService-Info.plist from source control and keep only an example -->
<!-- sample/ios/sample/GoogleService-Info.example.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>API_KEY</key>
	<string>YOUR_IOS_API_KEY</string>
	<key>GCM_SENDER_ID</key>
	<string>YOUR_GCM_SENDER_ID</string>
	<key>PLIST_VERSION</key>
	<string>1</string>
	<key>BUNDLE_ID</key>
	<string>com.usercentrics.sdk.mediation.test</string>
	<key>PROJECT_ID</key>
	<string>YOUR_PROJECT_ID</string>
	<key>STORAGE_BUCKET</key>
	<string>YOUR_STORAGE_BUCKET</string>
	<key>GOOGLE_APP_ID</key>
	<string>YOUR_GOOGLE_APP_ID</string>
</dict>
</plist>

Also update .gitignore to exclude the real file:

# Firebase iOS config (do not commit real credentials)
sample/ios/sample/GoogleService-Info.plist

And adjust sample/README.md to reference GoogleService-Info.example.plist as the template users should copy and fill with their own values.

Comment thread sample/README.md

First, you will need to run **Metro**, the JavaScript build tool for React Native.
### All Platforms
- **Node.js 18.0+** (LTS recommended)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NITPICK] README lists Node.js 18.0+ as a prerequisite but sample/package.json (project context) requires Node >=20.19.4. Align the README Node requirement with the project's package.json (or explain versions supported) to avoid developer confusion.

### All Platforms
- **Node.js 20.19.4+** (must match `"engines"` in `sample/package.json`)
- **npm 9.0+** or **Yarn 1.22+**
- **React Native 0.81.4+**
- **Watchman** (recommended for file watching)

Comment thread sample/README.md Outdated
Comment on lines +251 to +260
### Firebase Config Files

Firebase requires platform-specific config files that are **not committed** to this repository:

| Platform | File | Location |
|----------|------|----------|
| Android | `google-services.json` | `android/app/` |
| iOS | `GoogleService-Info.plist` | `ios/sample/` |

Obtain these from the Firebase Console for the `in-app-sdk` project and place them in the locations above before building. The Xcode project already has `GoogleService-Info.plist` wired as a build resource in `project.pbxproj`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CRITICAL_BUG] README clearly states Firebase config files are NOT committed, but the PR adds GoogleService-Info.plist to the repo. Update the README to reflect current repository policy OR (preferred) remove the committed plist and keep README's guidance. Ensure README steps instruct addition of real config files into platform folders and do not encourage committing secrets.

### Firebase Config Files

Firebase requires platform-specific config files that **must not be committed** to this repository:

| Platform | File                     | Location        |
|----------|--------------------------|-----------------|
| Android  | `google-services.json`   | `android/app/`  |
| iOS      | `GoogleService-Info.plist` | `ios/sample/` |

Obtain these from the Firebase Console for the `in-app-sdk` project and place them in the locations above before building. The Xcode project is already configured to look for `GoogleService-Info.plist` at `ios/sample/GoogleService-Info.plist`, but the file should be added locally and **must not be committed**.

dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
mavenLocal()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[REFACTORING] mavenLocal() was added to plugin/dependency resolution repositories. This can make builds non-reproducible (local artifacts may shadow public versions). If you only need it for local development, make it conditional (e.g. based on an env var) or document the reason. Avoid shipping mavenLocal() in CI/release-focused sample settings unless intentional.

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        if (System.getenv("USE_MAVEN_LOCAL") == "true") {
            mavenLocal()
        }
        google()
        mavenCentral()
        maven { url = uri("$rootDir/../node_modules/@react-native/gradle-plugin") }
        maven { url = uri("https://www.jitpack.io") }
    }
}

Comment thread sample/src/App.tsx
Comment on lines +7 to +10
// Set to true when testing consent mediation. Keep false for normal builds.
const MEDIATION_TEST_ENABLED = true;
const SETTINGS_ID = '3C9-yvno8-dEzy';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NITPICK] MEDIATION_TEST_ENABLED is set to true by default in the sample. This can unintentionally enable consent mediation and propagate consent to mediation partners during local runs. Recommend changing the default to false and provide an environment/config flag (or documented constant) so developers opt-in explicitly when testing mediation.

// Set to true when testing consent mediation. Keep false for normal builds.
const MEDIATION_TEST_ENABLED = false;
const SETTINGS_ID = '3C9-yvno8-dEzy';

Comment on lines +12 to +20
React.useEffect(() => {
Usercentrics.status().then(status => {
if (status.shouldCollectConsent) {
showFirstLayer();
} else {
applyConsent(status.consents);
}
});
}, []);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[VALIDATION] The useEffect calls Usercentrics.status().then(...) but does not handle rejection. Add .catch(...) or use try/catch with async/await to avoid unhandled promise rejections if status() fails (network or initialization error). For example, catch and log errors and fall back to a safe default behaviour.

React.useEffect(() => {
    let cancelled = false;

    Usercentrics.status()
        .then(status => {
            if (cancelled) return;
            if (status.shouldCollectConsent) {
                showFirstLayer();
            } else {
                applyConsent(status.consents);
            }
        })
        .catch(error => {
            console.warn('Usercentrics.status() failed', error);
            // Optionally continue without auto-showing the banner
        });

    return () => {
        cancelled = true;
    };
}, []);

Comment on lines +34 to +43
function handleUserResponse(response: UsercentricsConsentUserResponse | null) {
console.log('Consents ->', response?.consents);
console.log('User Interaction ->', response?.userInteraction);
console.log('Controller Id ->', response?.controllerId);
applyConsent(response?.consents);
}

async function getBannerSettings() {
const variant = await Usercentrics.getABTestingVariant()
let bannerSettings: BannerSettings;
function applyConsent(_consents?: UsercentricsServiceConsent[] | null) {
// https://docs.usercentrics.com/cmp_in_app_sdk/latest/apply_consent/apply-consent/#apply-consent-to-each-service
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[REFACTORING] handleUserResponse currently logs the response and calls applyConsent(response?.consents) but applyConsent is a no-op. Either implement applyConsent to actually apply consents to your sample integrations (or map/translate them to partner SDK calls), or clearly mark it as a TODO and avoid calling it. Leaving it empty is confusing for someone testing mediation.

function applyConsent(consents?: UsercentricsServiceConsent[] | null) {
    if (!consents) {
        return;
    }

    // Example: log per-service consent that would be forwarded to mediated SDKs
    consents.forEach(serviceConsent => {
        console.log(
            `Applying consent for service ${serviceConsent.templateId} (${serviceConsent.dataProcessor}):`,
            serviceConsent.status,
        );
        // Here you could map to partner SDK calls, e.g. Firebase, if not using mediation.
    });
}

Comment on lines +9 to +14
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
<string>CA92.1</string>
<string>1C8F.1</string>
<string>C56D.1</string>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[VALIDATION] You changed NSPrivacyAccessedAPICategory values and the associated reason codes (swapped 'UserDefaults' and 'FileTimestamp' categories and updated reason codes). Verify that the chosen NSPrivacyAccessedAPIType values and the reason codes conform to Apple's privacy requirements and the exact API access reasons expected by Firebase. Incorrect categories/reasons may cause App Store review issues or incorrect privacy declarations.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSPrivacyAccessedAPITypes</key>
	<array>
		<dict>
			<key>NSPrivacyAccessedAPIType</key>
			<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
			<key>NSPrivacyAccessedAPITypeReasons</key>
			<array>
				<!-- Limit reasons to those actually required by Firebase for NSUserDefaults -->
				<string>CA92.1</string>
			</array>
		</dict>
		<dict>
			<key>NSPrivacyAccessedAPIType</key>
			<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
			<key>NSPrivacyAccessedAPITypeReasons</key>
			<array>
				<string>C617.1</string>
			</array>
		</dict>
		<dict>
			<key>NSPrivacyAccessedAPIType</key>
			<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
			<key>NSPrivacyAccessedAPITypeReasons</key>
			<array>
				<string>35F9.1</string>
			</array>
		</dict>
	</array>
	<key>NSPrivacyCollectedDataTypes</key>
	<array/>
	<key>NSPrivacyTracking</key>
	<false/>
</dict>
</plist>

@pantoaibot
Copy link
Copy Markdown

pantoaibot Bot commented May 8, 2026

Reviewed up to commit:554c528c94b959340a0bb05229fbbb9dbdfde5cf

Reviewed by Panto AI

namespace = "com.usercentrics.reactnativesdk.sample"
defaultConfig {
applicationId = "com.usercentrics.reactnativesdk.sample"
applicationId = "com.usercentrics.sdk.mediation.test"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Architect Review — HIGH

The Android applicationId was changed to com.usercentrics.sdk.mediation.test, but the React Native CLI configuration still uses com.usercentrics.reactnativesdk.sample (in sample/react-native.config.js and sample/app.json), so CLI flows like npm run android can build the APK but then try to launch a non-existent package and fail.

Suggestion: Align the Android package identifiers by updating sample/react-native.config.js and sample/app.json to use com.usercentrics.sdk.mediation.test so all RN CLI scripts target the same applicationId as the Gradle config.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is an **Architect / Logical Review** comment left during a code review. These reviews are first-class, important findings — not optional suggestions. Do NOT dismiss this as a 'big architectural change' just because the title says architect review; most of these can be resolved with a small, localized fix once the intent is understood.

**Path:** sample/android/app/build.gradle.kts
**Line:** 15:15
**Comment:**
	*HIGH: The Android applicationId was changed to `com.usercentrics.sdk.mediation.test`, but the React Native CLI configuration still uses `com.usercentrics.reactnativesdk.sample` (in sample/react-native.config.js and sample/app.json), so CLI flows like `npm run android` can build the APK but then try to launch a non-existent package and fail.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
If a suggested approach is provided above, use it as the authoritative instruction. If no explicit code suggestion is given, you MUST still draft and apply your own minimal, localized fix — do not punt back with 'no suggestion provided, review manually'. Keep the change as small as possible: add a guard clause, gate on a loading state, reorder an await, wrap in a conditional, etc. Do not refactor surrounding code or expand scope beyond the finding.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix

Comment thread sample/ios/sample/GoogleService-Info.plist Outdated
Comment on lines +41 to +43
function applyConsent(_consents?: UsercentricsServiceConsent[] | null) {
// https://docs.usercentrics.com/cmp_in_app_sdk/latest/apply_consent/apply-consent/#apply-consent-to-each-service
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Consent apply is no-op 🐞 Bug ≡ Correctness

HomeScreen calls applyConsent(status.consents) on mount and after user interaction, but
applyConsent is an empty stub. As a result, existing consents and user decisions are never
applied/propagated from the Home screen flow.
Agent Prompt
### Issue description
`HomeScreen.applyConsent(...)` is currently a no-op, but it’s called when `shouldCollectConsent` is false and after `showFirstLayer/showSecondLayer` responses. This means the Home screen flow never applies/handles the consents it retrieves.

### Issue Context
The sample already contains an `applyConsents(...)` implementation pattern in `CustomUI.tsx` (iterating consents and logging). The Home screen should do something equivalent (at minimum) and/or trigger partner updates if that’s the point of the mediation demo.

### Fix Focus Areas
- sample/src/screens/Home.tsx[12-19]
- sample/src/screens/Home.tsx[34-43]
- sample/src/screens/CustomUI.tsx[297-302]

### Suggested fix
- Implement `applyConsent` to process the provided `UsercentricsServiceConsent[]`:
  - At minimum: iterate and log `templateId/status/type` (like `CustomUI.tsx`).
  - If the sample intends to demonstrate partner enable/disable: route consent state to the relevant SDK(s) (or explicitly note that mediation handles it and remove the misleading calls/README text).
- Ensure `applyConsent(undefined/null)` is handled safely (early return).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread sample/android/app/build.gradle.kts Outdated
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.facebook.react")
id("com.google.gms.google-services")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Enabling the Google Services plugin unconditionally makes Android builds depend on android/app/google-services.json; without that file the Gradle task fails and the sample cannot build out-of-the-box. Apply the plugin conditionally when the config file exists (or provide a checked-in non-sensitive sample config for CI/dev builds). [incomplete implementation]

Severity Level: Critical 🚨
- ❌ Android sample build fails without Firebase config present.
- ⚠️ New developers blocked from running consent mediation sample.
Steps of Reproduction ✅
1. From the repo root, run the Android sample build as documented in `sample/README.md`
lines 93-101 (e.g. `cd sample && npm run android`), which uses the Gradle script at
`sample/android/app/build.gradle.kts`.

2. During configuration, Gradle applies the Google Services plugin declared at
`sample/android/app/build.gradle.kts:1-6`, specifically line 5
`id("com.google.gms.google-services")`, to the `app` module.

3. The Google Services plugin requires a `google-services.json` file in the Android app
module; a repo-wide search (`Glob` for `**/google-services.json`) confirms no such file
exists anywhere under `/workspace/react-native-sdk`.

4. Because the plugin is enabled but the config file is missing, the Android build fails
with the standard `File google-services.json is missing` error, preventing the sample from
building out-of-the-box until developers either add a Firebase project config or manually
remove/disable the plugin.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** sample/android/app/build.gradle.kts
**Line:** 5:5
**Comment:**
	*Incomplete Implementation: Enabling the Google Services plugin unconditionally makes Android builds depend on `android/app/google-services.json`; without that file the Gradle task fails and the sample cannot build out-of-the-box. Apply the plugin conditionally when the config file exists (or provide a checked-in non-sensitive sample config for CI/dev builds).

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +12 to +20
React.useEffect(() => {
Usercentrics.status().then(status => {
if (status.shouldCollectConsent) {
showFirstLayer();
} else {
applyConsent(status.consents);
}
});
}, []);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The startup consent check handles only the fulfilled path and never handles rejection, so any failure from status() becomes an unhandled promise rejection and leaves the screen in an inconsistent state. Add error handling (catch or try/catch) and a fallback flow so initialization failures are handled explicitly. [possible bug]

Severity Level: Major ⚠️
- ❌ Unhandled promise rejections on initialization failures in HomeScreen.
- ⚠️ Consent banner may never show after SDK readiness errors.
Steps of Reproduction ✅
1. Launch the sample app so `App` renders the navigation stack defined in
`sample/src/App.tsx:23-29`, where the initial route is `Home` mapped to `HomeScreen` from
`sample/src/screens/Home.tsx:11`.

2. When `HomeScreen` mounts, the effect at `sample/src/screens/Home.tsx:12-20` runs and
calls `Usercentrics.status().then(status => { ... })` without any `.catch()` or
`try/catch` around the Promise.

3. The SDK wrapper implementation in `src/Usercentrics.tsx:34-36` shows `status()` returns
`RNUsercentricsModule.isReady()`. The test `testStatusWithError` in
`src/__tests__/index.test.ts:22-32` configures `RNUsercentricsModule.isReady` to
`Promise.reject("Failed")` and verifies that `Usercentrics.status()` propagates this
rejection, demonstrating that `status()` legitimately rejects on error.

4. In a real error scenario (e.g., native `isReady` rejects due to network or
configuration issues), `Usercentrics.status()` will reject, and since the `HomeScreen`
effect does not handle rejections, this becomes an unhandled Promise rejection in React
Native, leaving the screen without any fallback (no banner shown, `applyConsent` never
called) and surfacing as an unhandled error instead of a controlled "failed to initialize
consent" state.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** sample/src/screens/Home.tsx
**Line:** 12:20
**Comment:**
	*Possible Bug: The startup consent check handles only the fulfilled path and never handles rejection, so any failure from `status()` becomes an unhandled promise rejection and leaves the screen in an inconsistent state. Add error handling (`catch` or `try/catch`) and a fallback flow so initialization failures are handled explicitly.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 8, 2026

CodeAnt AI finished reviewing your PR.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (3)
sample/android/app/build.gradle.kts (1)

83-84: ⚡ Quick win

Firebase BOM 33.13.0 is several major releases behind the current 34.12.0.

The Firebase Android BoM has been updated to v34.1.0 (and subsequently to 34.12.0). As a sample app this is lower risk, but staying on 33.x means missing security patches and behavioural fixes in Analytics. Consider bumping to the latest BOM before publishing.

🤖 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 `@sample/android/app/build.gradle.kts` around lines 83 - 84, Update the
Firebase BoM version used in the Gradle dependencies: find the
implementation(platform("com.google.firebase:firebase-bom:33.13.0")) line and
replace the BOM version with the current release (e.g., 34.12.0) so the
implementation("com.google.firebase:firebase-analytics") dependency picks up the
latest matching Firebase artifact versions; ensure you run a build to verify
compatibility and adjust any downstream Firebase dependency versions if needed.
sample/android/build.gradle.kts (1)

10-10: ⚡ Quick win

Move google-services version to the Gradle version catalog for consistency.

The google-services plugin at 4.4.2 is two patch versions behind the current 4.4.4. More importantly, this dependency uses a hardcoded version string while the other Gradle plugins (lines 7–9) reference versions from the catalog. Add google-services = "4.4.4" to gradle/libs.versions.toml and update line 10 to use classpath(versions.google.services).

🤖 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 `@sample/android/build.gradle.kts` at line 10, Add a new entry in the Gradle
version catalog (gradle/libs.versions.toml) like google-services = "4.4.4" and
replace the hardcoded plugin declaration
classpath("com.google.gms:google-services:4.4.2") in build.gradle.kts with the
catalog reference using versions.google.services so the google‑services plugin
uses the centralized version; ensure you reference the exact key
"google-services" in the catalog and "versions.google.services" in the classpath
call.
sample/ios/Podfile (1)

27-27: ⚡ Quick win

Pin FirebaseAnalytics to a specific version for reproducible builds.

Without a version constraint, pod install can silently resolve to a new major/minor release that breaks the Firebase ↔ Usercentrics mediation integration. Consider locking to the version in use (or at least a compatible range).

♻️ Proposed fix
-  pod 'FirebaseAnalytics'
+  pod 'FirebaseAnalytics', '~> 11.0'   # pin to the major in use; update alongside Firebase BOM on Android
🤖 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 `@sample/ios/Podfile` at line 27, Pin the FirebaseAnalytics pod to a specific
version or a constrained version range in the Podfile to ensure reproducible
builds and avoid breaking changes; locate the pod declaration "pod
'FirebaseAnalytics'" and replace it with a fixed version specifier or compatible
range (e.g., '= x.y.z' or '~> x.y') that matches the currently used Firebase
Analytics release.
🤖 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 `@sample/android/settings.gradle.kts`:
- Line 18: The build currently calls mavenLocal() which can make CI builds
non-reproducible; remove that call from the settings.gradle.kts or wrap it in a
conditional that only enables local Maven resolution for developer machines
(e.g., check a Gradle project property or environment variable such as CI or a
custom property like useLocalMaven), add a short comment explaining why the
guard exists (only for local snapshot testing of react-native-usercentrics), and
ensure the unique symbol mavenLocal() is only executed when the guard permits so
CI and shared builds use only declared remote repositories.

In `@sample/ios/sample/GoogleService-Info.plist`:
- Around line 5-30: Replace all real Firebase values in GoogleService-Info.plist
(API_KEY, GCM_SENDER_ID, GOOGLE_APP_ID, DATABASE_URL, STORAGE_BUCKET, PROJECT_ID
and any other identifying entries) with descriptive placeholder strings (e.g.,
YOUR_FIREBASE_API_KEY, YOUR_GCM_SENDER_ID, YOUR_GOOGLE_APP_ID,
YOUR_DATABASE_URL, YOUR_STORAGE_BUCKET, YOUR_PROJECT_ID) and remove any live
project identifiers; then add concise setup instructions to sample/README.md
telling users to download their own GoogleService-Info.plist from the Firebase
Console and place it in the sample/ios/sample/ directory (or an equivalent path)
before running the sample.

In `@sample/README.md`:
- Around line 31-51: The fenced code block showing the project tree (the block
beginning with ``` and the "sample/" tree) is missing a language specifier;
update that opening fence to include a tag such as `text` or `plaintext` (e.g.,
change ``` to ```text) so markdownlint MD040 is satisfied and renderers get
syntax awareness for the tree block in README.md.

In `@sample/src/App.tsx`:
- Around line 7-9: The MEDIATION_TEST_ENABLED constant is set to true against
its comment and should be false for normal builds; change MEDIATION_TEST_ENABLED
to false. Replace the hardcoded live settings ID in SETTINGS_ID
('3C9-yvno8-dEzy') with a clear placeholder (e.g.,
'<YOUR_USERCENTRICS_SETTINGS_ID>') and update any README/setup docs to instruct
developers to provide their own ID and required Google service files when
enabling mediation mode. Ensure you only change the values of
MEDIATION_TEST_ENABLED and SETTINGS_ID in App.tsx.

In `@sample/src/screens/Home.tsx`:
- Around line 84-85: The onPress handlers call Usercentrics.status() and discard
its result and errors before calling navigation.navigate (see
Usercentrics.status and navigation.navigate inside the Button onPress
callbacks); either await and handle the result/error (e.g., wrap await
Usercentrics.status() in try/catch and only navigate on success or log/handle
failures) or remove the unnecessary await if you don't need a readiness barrier
— update both Button handlers (the async onPress functions) accordingly so
errors from Usercentrics.status() are not ignored.
- Around line 12-20: HomeScreen calls Usercentrics.status() before the SDK is
initialized in App (Usercentrics.configure()), causing race/unhandled-rejection
issues; hoist Usercentrics.configure() to module scope in App.tsx so it runs
synchronously before any components mount, and update the Home.tsx effect that
calls Usercentrics.status() to handle promise rejections (add a .catch() and
fail-safe branch) so errors from Usercentrics.status() cannot go unhandled.

---

Nitpick comments:
In `@sample/android/app/build.gradle.kts`:
- Around line 83-84: Update the Firebase BoM version used in the Gradle
dependencies: find the
implementation(platform("com.google.firebase:firebase-bom:33.13.0")) line and
replace the BOM version with the current release (e.g., 34.12.0) so the
implementation("com.google.firebase:firebase-analytics") dependency picks up the
latest matching Firebase artifact versions; ensure you run a build to verify
compatibility and adjust any downstream Firebase dependency versions if needed.

In `@sample/android/build.gradle.kts`:
- Line 10: Add a new entry in the Gradle version catalog
(gradle/libs.versions.toml) like google-services = "4.4.4" and replace the
hardcoded plugin declaration classpath("com.google.gms:google-services:4.4.2")
in build.gradle.kts with the catalog reference using versions.google.services so
the google‑services plugin uses the centralized version; ensure you reference
the exact key "google-services" in the catalog and "versions.google.services" in
the classpath call.

In `@sample/ios/Podfile`:
- Line 27: Pin the FirebaseAnalytics pod to a specific version or a constrained
version range in the Podfile to ensure reproducible builds and avoid breaking
changes; locate the pod declaration "pod 'FirebaseAnalytics'" and replace it
with a fixed version specifier or compatible range (e.g., '= x.y.z' or '~> x.y')
that matches the currently used Firebase Analytics release.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1180b34d-b563-4093-b52b-428095f65e69

📥 Commits

Reviewing files that changed from the base of the PR and between 97b5e8c and 554c528.

⛔ Files ignored due to path filters (1)
  • sample/ios/Podfile.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • sample/README.md
  • sample/android/app/build.gradle.kts
  • sample/android/app/src/main/AndroidManifest.xml
  • sample/android/build.gradle.kts
  • sample/android/settings.gradle.kts
  • sample/ios/Podfile
  • sample/ios/sample.xcodeproj/project.pbxproj
  • sample/ios/sample/AppDelegate.swift
  • sample/ios/sample/GoogleService-Info.plist
  • sample/ios/sample/Info.plist
  • sample/ios/sample/PrivacyInfo.xcprivacy
  • sample/src/App.tsx
  • sample/src/screens/Home.tsx

dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
mavenLocal()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

mavenLocal() may cause non-reproducible builds in CI.

Resolving from the local Maven repository ties the build outcome to whatever artifacts happen to be cached on each machine. If this was added to pick up a locally-built react-native-usercentrics snapshot, consider adding a comment explaining the intent and guarding it conditionally — or removing it before the PR lands if it was only needed during local development.

🔧 Example of conditional guard
-        mavenLocal()
+        // Uncomment only when testing against a locally-published SDK snapshot:
+        // mavenLocal()
         google()
📝 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.

Suggested change
mavenLocal()
// Uncomment only when testing against a locally-published SDK snapshot:
// mavenLocal()
🤖 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 `@sample/android/settings.gradle.kts` at line 18, The build currently calls
mavenLocal() which can make CI builds non-reproducible; remove that call from
the settings.gradle.kts or wrap it in a conditional that only enables local
Maven resolution for developer machines (e.g., check a Gradle project property
or environment variable such as CI or a custom property like useLocalMaven), add
a short comment explaining why the guard exists (only for local snapshot testing
of react-native-usercentrics), and ensure the unique symbol mavenLocal() is only
executed when the guard permits so CI and shared builds use only declared remote
repositories.

Comment thread sample/ios/sample/GoogleService-Info.plist Outdated
Comment thread sample/README.md
Comment on lines +31 to 51
```
sample/
├── src/
│ ├── App.tsx # SDK initialisation and navigation root
│ └── screens/
│ ├── Home.tsx # Main consent flow (auto status check, first/second layer)
│ ├── CustomUI.tsx # Programmatic API demo (GDPR / TCF / CCPA)
│ ├── WebviewIntegrationScreen.tsx # In-App SDK → Browser SDK session handoff
│ └── GppTestingScreen.tsx # GPP string and section-change event testing
├── android/ # Android project (Kotlin, Firebase integrated)
│ ├── app/
│ │ ├── build.gradle.kts # Firebase BOM, google-services plugin
│ │ └── src/main/AndroidManifest.xml# Firebase collection flags (all false by default)
│ └── build.gradle.kts # google-services classpath
└── ios/ # iOS project (Swift, Firebase integrated)
├── Podfile # FirebaseAnalytics pod
└── sample/
├── AppDelegate.swift # FirebaseApp.configure() call
├── Info.plist # FIREBASE_ANALYTICS_COLLECTION_ENABLED = false
└── PrivacyInfo.xcprivacy # NSUserDefaults access reasons for Firebase
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Missing language specifier on fenced code block (MD040).

The code block at line 31 has no language tag. Adding one (e.g., text or plaintext) satisfies the markdownlint rule and enables syntax awareness in tools that render the file.

🔧 Proposed fix
-```
+```text
 sample/
 ├── src/
📝 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.

Suggested change
```
sample/
├── src/
│ ├── App.tsx # SDK initialisation and navigation root
│ └── screens/
│ ├── Home.tsx # Main consent flow (auto status check, first/second layer)
│ ├── CustomUI.tsx # Programmatic API demo (GDPR / TCF / CCPA)
│ ├── WebviewIntegrationScreen.tsx # In-App SDK → Browser SDK session handoff
│ └── GppTestingScreen.tsx # GPP string and section-change event testing
├── android/ # Android project (Kotlin, Firebase integrated)
│ ├── app/
│ │ ├── build.gradle.kts # Firebase BOM, google-services plugin
│ │ └── src/main/AndroidManifest.xml# Firebase collection flags (all false by default)
│ └── build.gradle.kts # google-services classpath
└── ios/ # iOS project (Swift, Firebase integrated)
├── Podfile # FirebaseAnalytics pod
└── sample/
├── AppDelegate.swift # FirebaseApp.configure() call
├── Info.plist # FIREBASE_ANALYTICS_COLLECTION_ENABLED = false
└── PrivacyInfo.xcprivacy # NSUserDefaults access reasons for Firebase
```
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 31-31: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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 `@sample/README.md` around lines 31 - 51, The fenced code block showing the
project tree (the block beginning with ``` and the "sample/" tree) is missing a
language specifier; update that opening fence to include a tag such as `text` or
`plaintext` (e.g., change ``` to ```text) so markdownlint MD040 is satisfied and
renderers get syntax awareness for the tree block in README.md.

Comment thread sample/src/App.tsx
Comment on lines +7 to +9
// Set to true when testing consent mediation. Keep false for normal builds.
const MEDIATION_TEST_ENABLED = true;
const SETTINGS_ID = '3C9-yvno8-dEzy';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

MEDIATION_TEST_ENABLED is true contrary to its own comment, and SETTINGS_ID should be a placeholder.

Two distinct issues on these lines:

  1. Wrong default value: The inline comment explicitly says "Keep false for normal builds", yet the constant is set to true. Anyone who clones the repo and runs the sample without reading the README will get mediation mode unexpectedly, which requires google-services.json / GoogleService-Info.plist to be present — causing a build or runtime failure.

  2. Real settings ID committed: '3C9-yvno8-dEzy' is a live Usercentrics settings ID hardcoded in a public repository. Per coding guidelines for sample apps, use a placeholder value and document the setup steps.

🔧 Proposed fix
-// Set to true when testing consent mediation. Keep false for normal builds.
-const MEDIATION_TEST_ENABLED = true;
-const SETTINGS_ID = '3C9-yvno8-dEzy';
+// Set to true when testing consent mediation. Keep false for normal builds.
+const MEDIATION_TEST_ENABLED = false;
+// Replace with your own Usercentrics Settings ID from https://account.usercentrics.eu
+const SETTINGS_ID = 'YOUR_SETTINGS_ID';

As per coding guidelines, {sample,samples,example,examples,demo,demos}/**/*: "If a secret is needed in a sample app, use a placeholder value and document the setup."

📝 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.

Suggested change
// Set to true when testing consent mediation. Keep false for normal builds.
const MEDIATION_TEST_ENABLED = true;
const SETTINGS_ID = '3C9-yvno8-dEzy';
// Set to true when testing consent mediation. Keep false for normal builds.
const MEDIATION_TEST_ENABLED = false;
// Replace with your own Usercentrics Settings ID from https://account.usercentrics.eu
const SETTINGS_ID = 'YOUR_SETTINGS_ID';
🤖 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 `@sample/src/App.tsx` around lines 7 - 9, The MEDIATION_TEST_ENABLED constant
is set to true against its comment and should be false for normal builds; change
MEDIATION_TEST_ENABLED to false. Replace the hardcoded live settings ID in
SETTINGS_ID ('3C9-yvno8-dEzy') with a clear placeholder (e.g.,
'<YOUR_USERCENTRICS_SETTINGS_ID>') and update any README/setup docs to instruct
developers to provide their own ID and required Google service files when
enabling mediation mode. Ensure you only change the values of
MEDIATION_TEST_ENABLED and SETTINGS_ID in App.tsx.

Comment on lines +12 to +20
React.useEffect(() => {
Usercentrics.status().then(status => {
if (status.shouldCollectConsent) {
showFirstLayer();
} else {
applyConsent(status.consents);
}
});
}, []);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Usercentrics.status() is called before Usercentrics.configure() — SDK not initialized.

React fires useEffect callbacks bottom-up (children before parents). Because HomeScreen is a descendant of App, its effect runs first — calling Usercentrics.status() — and only then does App's effect run and call Usercentrics.configure(). The SDK has not been initialized when status() is invoked, so the call will either throw, resolve incorrectly, or silently no-op depending on the SDK's internal guards.

The promise also has no .catch(), so any rejection goes unhandled and may crash the app on React Native.

The simplest fix is to move configure() to module level in App.tsx so it runs synchronously before any component mounts:

🐛 Proposed fix — move configure() to module scope and add error handling in HomeScreen

In App.tsx, hoist configure() above the component:

+// Initialize SDK synchronously before React renders
+Usercentrics.configure({
+    settingsId: SETTINGS_ID,
+    loggerLevel: UsercentricsLoggerLevel.debug,
+    consentMediation: MEDIATION_TEST_ENABLED,
+});
+
 const App = () => {
-    React.useEffect(() => {
-        Usercentrics.configure({
-            settingsId: SETTINGS_ID,
-            loggerLevel: UsercentricsLoggerLevel.debug,
-            consentMediation: MEDIATION_TEST_ENABLED,
-        });
-    }, []);
     return ( ... );
 };

In Home.tsx, add error handling:

 React.useEffect(() => {
     Usercentrics.status().then(status => {
         if (status.shouldCollectConsent) {
             showFirstLayer();
         } else {
             applyConsent(status.consents);
         }
-    });
+    }).catch(error => {
+        console.error('Usercentrics status error:', error);
+    });
 }, []);
📝 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.

Suggested change
React.useEffect(() => {
Usercentrics.status().then(status => {
if (status.shouldCollectConsent) {
showFirstLayer();
} else {
applyConsent(status.consents);
}
});
}, []);
React.useEffect(() => {
Usercentrics.status().then(status => {
if (status.shouldCollectConsent) {
showFirstLayer();
} else {
applyConsent(status.consents);
}
}).catch(error => {
console.error('Usercentrics status error:', error);
});
}, []);
🤖 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 `@sample/src/screens/Home.tsx` around lines 12 - 20, HomeScreen calls
Usercentrics.status() before the SDK is initialized in App
(Usercentrics.configure()), causing race/unhandled-rejection issues; hoist
Usercentrics.configure() to module scope in App.tsx so it runs synchronously
before any components mount, and update the Home.tsx effect that calls
Usercentrics.status() to handle promise rejections (add a .catch() and fail-safe
branch) so errors from Usercentrics.status() cannot go unhandled.

Comment on lines +84 to +85
<Button onPress={async () => { await Usercentrics.status(); navigation.navigate('CustomUI'); }} title="Custom UI" />
<Button onPress={async () => { await Usercentrics.status(); navigation.navigate('WebviewIntegration'); }} title="Webview Integration" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Discarded await Usercentrics.status() result before navigation — misleading and unhandled.

The status() result is ignored and no error is handled. If this is intended as a readiness barrier before navigating, add at least a .catch(), or remove the await entirely if it serves no purpose.

🔧 Proposed fix
-<Button onPress={async () => { await Usercentrics.status(); navigation.navigate('CustomUI'); }} title="Custom UI" />
-<Button onPress={async () => { await Usercentrics.status(); navigation.navigate('WebviewIntegration'); }} title="Webview Integration" />
+<Button onPress={() => navigation.navigate('CustomUI')} title="Custom UI" />
+<Button onPress={() => navigation.navigate('WebviewIntegration')} title="Webview Integration" />
📝 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.

Suggested change
<Button onPress={async () => { await Usercentrics.status(); navigation.navigate('CustomUI'); }} title="Custom UI" />
<Button onPress={async () => { await Usercentrics.status(); navigation.navigate('WebviewIntegration'); }} title="Webview Integration" />
<Button onPress={() => navigation.navigate('CustomUI')} title="Custom UI" />
<Button onPress={() => navigation.navigate('WebviewIntegration')} title="Webview Integration" />
🤖 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 `@sample/src/screens/Home.tsx` around lines 84 - 85, The onPress handlers call
Usercentrics.status() and discard its result and errors before calling
navigation.navigate (see Usercentrics.status and navigation.navigate inside the
Button onPress callbacks); either await and handle the result/error (e.g., wrap
await Usercentrics.status() in try/catch and only navigate on success or
log/handle failures) or remove the unnecessary await if you don't need a
readiness barrier — update both Button handlers (the async onPress functions)
accordingly so errors from Usercentrics.status() are not ignored.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
sample/README.md (1)

31-31: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to the project-tree fenced block.

The code fence at Line 31 is missing a language specifier, which still triggers MD040.

Proposed fix
-```
+```text
 sample/
 ├── src/
 │   ├── App.tsx                          # SDK initialisation and navigation root
🤖 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 `@sample/README.md` at line 31, The README's project-tree fenced code block
(the triple-backtick block containing "sample/ ├── src/ ...") is missing a
language tag which triggers MD040; update that fenced block declaration (the
opening ``` line for the project-tree block) to include a language tag such as
"text" or "bash" so the block becomes ```text (or another appropriate tag) to
satisfy the linter and preserve formatting.
🤖 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.

Duplicate comments:
In `@sample/README.md`:
- Line 31: The README's project-tree fenced code block (the triple-backtick
block containing "sample/ ├── src/ ...") is missing a language tag which
triggers MD040; update that fenced block declaration (the opening ``` line for
the project-tree block) to include a language tag such as "text" or "bash" so
the block becomes ```text (or another appropriate tag) to satisfy the linter and
preserve formatting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ae249197-be56-4747-b649-b7a19292f597

📥 Commits

Reviewing files that changed from the base of the PR and between 554c528 and c51e619.

📒 Files selected for processing (2)
  • sample/.gitignore
  • sample/README.md
✅ Files skipped from review due to trivial changes (1)
  • sample/.gitignore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant