feat(MSDK-3794): Add Firebase mediation integration to React Native sample app#210
feat(MSDK-3794): Add Firebase mediation integration to React Native sample app#210asadraza-usercentrics wants to merge 4 commits intomasterfrom
Conversation
|
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 · |
|
Warning Rate limit exceeded
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 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis 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. ChangesFirebase Integration and Consent Mediation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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 |
Review Summary by QodoAdd Firebase mediation integration and comprehensive documentation to React Native sample app
WalkthroughsDescription• 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 Diagramflowchart 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"]
File Changes1. sample/android/app/build.gradle.kts
|
Code Review by Qodo
1.
|
|
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:
Potential breaking / noteworthy items:
|
| <key>API_KEY</key> | ||
| <string>AIzaSyCbVPJwkNblldnnC6drkANOFNBR0pc16vc</string> |
There was a problem hiding this comment.
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| <?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 |
There was a problem hiding this comment.
[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.plistAnd adjust sample/README.md to reference GoogleService-Info.example.plist as the template users should copy and fill with their own values.
|
|
||
| First, you will need to run **Metro**, the JavaScript build tool for React Native. | ||
| ### All Platforms | ||
| - **Node.js 18.0+** (LTS recommended) |
There was a problem hiding this comment.
[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)| ### 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`. |
There was a problem hiding this comment.
[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() |
There was a problem hiding this comment.
[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") }
}
}| // Set to true when testing consent mediation. Keep false for normal builds. | ||
| const MEDIATION_TEST_ENABLED = true; | ||
| const SETTINGS_ID = '3C9-yvno8-dEzy'; | ||
|
|
There was a problem hiding this comment.
[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';| React.useEffect(() => { | ||
| Usercentrics.status().then(status => { | ||
| if (status.shouldCollectConsent) { | ||
| showFirstLayer(); | ||
| } else { | ||
| applyConsent(status.consents); | ||
| } | ||
| }); | ||
| }, []); |
There was a problem hiding this comment.
[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;
};
}, []);| 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 | ||
| } |
There was a problem hiding this comment.
[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.
});
}| <string>NSPrivacyAccessedAPICategoryUserDefaults</string> | ||
| <key>NSPrivacyAccessedAPITypeReasons</key> | ||
| <array> | ||
| <string>C617.1</string> | ||
| <string>CA92.1</string> | ||
| <string>1C8F.1</string> | ||
| <string>C56D.1</string> |
There was a problem hiding this comment.
[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>|
Reviewed up to commit:554c528c94b959340a0bb05229fbbb9dbdfde5cf |
| namespace = "com.usercentrics.reactnativesdk.sample" | ||
| defaultConfig { | ||
| applicationId = "com.usercentrics.reactnativesdk.sample" | ||
| applicationId = "com.usercentrics.sdk.mediation.test" |
There was a problem hiding this comment.
🟠 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| function applyConsent(_consents?: UsercentricsServiceConsent[] | null) { | ||
| // https://docs.usercentrics.com/cmp_in_app_sdk/latest/apply_consent/apply-consent/#apply-consent-to-each-service | ||
| } |
There was a problem hiding this comment.
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
| id("com.android.application") | ||
| id("org.jetbrains.kotlin.android") | ||
| id("com.facebook.react") | ||
| id("com.google.gms.google-services") |
There was a problem hiding this comment.
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| React.useEffect(() => { | ||
| Usercentrics.status().then(status => { | ||
| if (status.shouldCollectConsent) { | ||
| showFirstLayer(); | ||
| } else { | ||
| applyConsent(status.consents); | ||
| } | ||
| }); | ||
| }, []); |
There was a problem hiding this comment.
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 finished reviewing your PR. |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (3)
sample/android/app/build.gradle.kts (1)
83-84: ⚡ Quick winFirebase BOM
33.13.0is several major releases behind the current34.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.xmeans 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 winMove
google-servicesversion to the Gradle version catalog for consistency.The google-services plugin at
4.4.2is two patch versions behind the current4.4.4. More importantly, this dependency uses a hardcoded version string while the other Gradle plugins (lines 7–9) reference versions from the catalog. Addgoogle-services = "4.4.4"togradle/libs.versions.tomland update line 10 to useclasspath(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 winPin
FirebaseAnalyticsto a specific version for reproducible builds.Without a version constraint,
pod installcan 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
⛔ Files ignored due to path filters (1)
sample/ios/Podfile.lockis excluded by!**/*.lock
📒 Files selected for processing (13)
sample/README.mdsample/android/app/build.gradle.ktssample/android/app/src/main/AndroidManifest.xmlsample/android/build.gradle.ktssample/android/settings.gradle.ktssample/ios/Podfilesample/ios/sample.xcodeproj/project.pbxprojsample/ios/sample/AppDelegate.swiftsample/ios/sample/GoogleService-Info.plistsample/ios/sample/Info.plistsample/ios/sample/PrivacyInfo.xcprivacysample/src/App.tsxsample/src/screens/Home.tsx
| dependencyResolutionManagement { | ||
| repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) | ||
| repositories { | ||
| mavenLocal() |
There was a problem hiding this comment.
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.
| 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.
| ``` | ||
| 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 | ||
| ``` |
There was a problem hiding this comment.
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.
| ``` | |
| 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.
| // Set to true when testing consent mediation. Keep false for normal builds. | ||
| const MEDIATION_TEST_ENABLED = true; | ||
| const SETTINGS_ID = '3C9-yvno8-dEzy'; |
There was a problem hiding this comment.
MEDIATION_TEST_ENABLED is true contrary to its own comment, and SETTINGS_ID should be a placeholder.
Two distinct issues on these lines:
-
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 requiresgoogle-services.json/GoogleService-Info.plistto be present — causing a build or runtime failure. -
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.
| // 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.
| React.useEffect(() => { | ||
| Usercentrics.status().then(status => { | ||
| if (status.shouldCollectConsent) { | ||
| showFirstLayer(); | ||
| } else { | ||
| applyConsent(status.consents); | ||
| } | ||
| }); | ||
| }, []); |
There was a problem hiding this comment.
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.
| 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.
| <Button onPress={async () => { await Usercentrics.status(); navigation.navigate('CustomUI'); }} title="Custom UI" /> | ||
| <Button onPress={async () => { await Usercentrics.status(); navigation.navigate('WebviewIntegration'); }} title="Webview Integration" /> |
There was a problem hiding this comment.
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.
| <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.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
sample/README.md (1)
31-31:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd 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
📒 Files selected for processing (2)
sample/.gitignoresample/README.md
✅ Files skipped from review due to trivial changes (1)
- sample/.gitignore
User description
PR description
Summary
Usercentrics.configure()intoApp.tsxviauseEffectwithMEDIATION_TEST_ENABLEDandSETTINGS_IDas the single control point formediation mode and settings configuration
Usercentrics.status()check onHomeScreenmount — shows firstlayer immediately if consent is required, otherwise applies existing consents
google-servicesplugin, Firebase BOM 33.13.0, all collectionflags disabled by default in
AndroidManifest.xmlFirebaseAnalyticspod,FirebaseApp.configure()inAppDelegate,FIREBASE_ANALYTICS_COLLECTION_ENABLED = falseinInfo.plist,PrivacyInfo.xcprivacyupdated with NSUserDefaults access reasonscom.usercentrics.sdk.mediation.testonboth platforms
sample/README.md— replaces the default RN boilerplate with afull guide covering prerequisites, project structure, screen descriptions,
run instructions, consent mediation setup, New Architecture toggle,
scripts reference, and troubleshooting
Summary by CodeRabbit
Documentation
New Features
Chores
CodeAnt-AI Description
Add Firebase consent mediation to the sample app and refresh the usage guide
What Changed
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:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
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:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
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.