-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
react-native-purchase-ui common-mark duplicate classes error (Dependency clash) #143
Comments
Have you already tried this? |
Yes in my own way, but this will not work sustainably. We shouldn't be editing the build.gradle directly in expo managed it apps. As it will get overwritten in prebuilds. I had to create a hacky expo plugin which I'm not confident in but works for now. Any longterm solutions? |
@raghav-phonebox this is my hacky solution /**
* This plugin configures the Crisp SDK integration for Android builds.
*
* Purpose:
* - Handles commonmark dependency conflicts in Crisp SDK
* - Resolves notification icon and color conflicts with Firebase
*
* What it does:
* 1. Excludes conflicting commonmark dependencies that cause duplicate class errors
* 2. Configures Android packaging options to handle resource conflicts
* 3. Adds the Crisp SDK dependency with proper exclusions
* 4. Adds manifest rules to handle notification conflicts
*
* Why we need it:
* The Crisp SDK has conflicting dependencies with other libraries in the project,
* specifically around the commonmark library and notification resources. This plugin ensures clean integration
* by managing these conflicts through Gradle configurations.
* links: https://community.revenuecat.com/sdks-51/react-native-purchase-ui-common-mark-duplicate-classes-error-4586
* links: https://github.com/RevenueCat/purchases-android/issues/1667
* links: https://github.com/RevenueCat/react-native-purchases/issues/1156
*/
const { withGradleProperties,withDangerousMod,withAndroidManifest } = require('expo/config-plugins');
const { mergeContents } = require('@expo/config-plugins/build/utils/generateCode');
const fs = require('fs/promises');
const withCrispConfig = (config) => {
// First apply the manifest modifications
config = withAndroidManifest(config,async (config) => {
const androidManifest = config.modResults;
// Add tools namespace if not present
if (!androidManifest.manifest.$) {
androidManifest.manifest.$ = {};
}
androidManifest.manifest.$['xmlns:tools'] = 'http://schemas.android.com/tools';
// Find the application node
const app = androidManifest.manifest.application[0];
if (!app['meta-data']) {
app['meta-data'] = [];
}
// Define the meta-data elements we need to modify
const metaDataElements = [
{
$: {
'android:name': 'com.google.firebase.messaging.default_notification_icon',
'android:resource': '@drawable/notification_icon',
'tools:replace': 'android:resource'
}
},
{
$: {
'android:name': 'com.google.firebase.messaging.default_notification_color',
'android:resource': '@color/notification_icon_color',
'tools:replace': 'android:resource'
}
}
];
// Update or add meta-data elements
metaDataElements.forEach(element => {
const existingIndex = app['meta-data'].findIndex(
data => data.$['android:name'] === element.$['android:name']
);
if (existingIndex >= 0) {
// Update existing element
app['meta-data'][existingIndex].$ = {
...app['meta-data'][existingIndex].$,
'tools:replace': 'android:resource'
};
} else {
// Add new element
app['meta-data'].push(element);
}
});
return config;
});
// Then apply the gradle modifications
return withDangerousMod(config,[
'android',
async (config) => {
const buildGradlePath = `${config.modRequest.platformProjectRoot}/app/build.gradle`;
const contents = await fs.readFile(buildGradlePath,'utf-8');
const packagingOptionsBlock = `
android {
packagingOptions {
resources {
pickFirsts += [
'org/commonmark/**',
'org/commonmark/internal/**',
'org/commonmark/internal/util/**',
'org/commonmark/internal/util/entities.properties',
'META-INF/LICENSE-notice.md',
'META-INF/LICENSE.md'
]
excludes += [
'META-INF/LICENSE',
'META-INF/NOTICE',
'META-INF/*.properties',
'META-INF/ASL2.0',
'META-INF/DEPENDENCIES'
]
}
}
}`;
const dependenciesBlock = `
configurations.all {
resolutionStrategy {
force 'org.commonmark:commonmark:0.21.0'
}
exclude group: 'com.atlassian.commonmark', module: 'commonmark'
exclude group: 'com.atlassian.commonmark', module: 'commonmark-ext-gfm-tables'
}
dependencies {
implementation('im.crisp:crisp-sdk:2.0.8') {
exclude group: 'com.atlassian.commonmark', module: 'commonmark'
exclude group: 'com.atlassian.commonmark', module: 'commonmark-ext-gfm-tables'
}
}`;
// Add packaging options
const contentsWithPackaging = mergeContents({
tag: 'crisp-sdk-packaging',
src: contents,
newSrc: packagingOptionsBlock,
anchor: /android\s*{/,
offset: 1,
comment: '//',
});
// Add dependencies and configurations
const newContents = mergeContents({
tag: 'crisp-sdk-dependencies',
src: contentsWithPackaging.contents || contentsWithPackaging,
newSrc: dependenciesBlock,
anchor: /dependencies\s*{/,
offset: 1,
comment: '//',
});
await fs.writeFile(buildGradlePath,newContents.contents || newContents);
return config;
},
]);
};
module.exports = withCrispConfig; |
@AyoCodess I believe this solution is updating the if that's the case, You can use Steps for using
"scripts": {
......
+ "postinstall": "patch-package"
}
It should patch your package, and every time anyone runs |
thank you! |
https://community.revenuecat.com/sdks-51/react-native-purchase-ui-common-mark-duplicate-classes-error-4586
we currently cant use crisp sdk if we have revenue cat in react native expo apps due to this issue.
is there a fix for expo apps?
The text was updated successfully, but these errors were encountered: