invertase / notifee

⚛️ A feature rich notifications library for React Native.
https://notifee.app
Apache License 2.0
1.8k stars 213 forks source link

Android: Circular referencing during evaluation for project ':app'. #210

Closed orbulant closed 1 year ago

orbulant commented 2 years ago

This happens only when i use Notifee with Huawei Messaging Service (@hmscore/react-native-hms-push).

I get this error when i run ./gradlew clean or when building my android app.

WARNING: Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.
It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html
--W- The variant: prodDebug, Use the json file: C:\myProject\android\app\agconnect-services.json

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\myProject\node_modules\@notifee\\react-native\android\build.gradle' line: 21

* What went wrong:
A problem occurred evaluating project ':notifee_react-native'.
> Circular referencing during evaluation for project ':app'.

Some things to note:

  1. If i remove agconnect-services.json (part of the @hmscore/react-native-hms-push), this error does not appear and i am successfully able to run ./gradlew clean.
  2. Commenting line 21 of the build.gradle file (C:\myAnonymousProject\node_modules\@notifee\react-native\android\build.gradle) poses no issue, and i am able to use the build and use the app as intended. However this is not a long term solution... of course... so thats why im here asking.

Any ideas?

Any recommendation on what to change in my build.gradle files (android/app and android/) that will help solve this issue?

Edit: Grammar and spelling mistakes.

mikehardy commented 2 years ago

Interesting - what gradle version, android gradle plugin version are you using? what other plugin lines are present in your android/build.gradle or android/app/build.gradle?

orbulant commented 2 years ago

Forgive me if i am not following any GitHub issues format.

Answers to your question:

  1. Gradle Version: 5.5 (from gradle-wrapper.properties)
  2. Android Gralde Plugin Version: "com.android.tools.build:gradle:3.4.2"

I have anonymized the name of my app.

In android/build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
//For Global Versioning
import groovy.json.JsonSlurper 

buildscript {
    ext {
        googlePlayServicesVersion = "+" // default: "+"
        firebaseMessagingVersion = "21.1.0" // default: "21.1.0"
        reactNativeFFmpegPackage = "min"

        buildToolsVersion = "28.0.3"
        minSdkVersion = 24
        compileSdkVersion = 30
        targetSdkVersion = 30
    }
    repositories {
        google()
        jcenter()
        maven { url 'https://developer.huawei.com/repo/' }
    }
    dependencies {
        classpath("com.android.tools.build:gradle:3.4.2")
        classpath 'com.google.gms:google-services:4.3.8'
        classpath 'com.huawei.agconnect:agcp:1.4.1.300'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        mavenCentral()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }
        maven {
            url "$rootDir/../node_modules/@notifee/react-native/android/libs"
        }
        maven { url 'https://developer.huawei.com/repo/' }
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

subprojects {
    ext {
      nodeAppVersion = getNodeAppVersion()
      nodeBuildVersion = getNodeBuildVersion()
    }
}

// For Global Versioning
def getNodeAppVersion() {
    def packageFile = new File("$rootDir/../package.json")
    def packageJson = new JsonSlurper().parseText(packageFile.text)
    return packageJson["aVersion"]
}

def getNodeBuildVersion() {
    def packageFile = new File("$rootDir/../package.json")
    def packageJson = new JsonSlurper().parseText(packageFile.text)
    return packageJson["bVersion"].toInteger()
}

In android/app/build.gradle

apply plugin: "com.android.application"
apply plugin: "com.huawei.agconnect"
apply plugin: 'com.google.gms.google-services'

import com.android.build.OutputFile

project.ext.react = [
    entryFile: "index.js",
    enableHermes: false,  // clean and rebuild if changing
]

apply from: "../../node_modules/react-native/react.gradle"

def enableSeparateBuildPerCPUArchitecture = false

def enableProguardInReleaseBuilds = true

def jscFlavor = 'org.webkit:android-jsc:+'

def enableHermes = project.ext.react.get("enableHermes", false);

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    packagingOptions {
      pickFirst '**/*.so'
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        applicationId "com.myanonymousapp"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode nodeBuildVersion
        versionName nodeAppVersion
        // versionCode 2
        // versionName "1.2"
        multiDexEnabled true
        missingDimensionStrategy 'react-native-camera', 'mlkit'
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }
    }
    signingConfigs {
        config {
            storeFile file('keystore.jks')
            storePassword '123456'
            keyAlias 'hmspkmyanonymousapp'
            keyPassword '123456'
        }
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword MYAPP_UPLOAD_STORE_PASSWORD
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword MYAPP_UPLOAD_KEY_PASSWORD
            }
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.config
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://facebook.github.io/react-native/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            // minifyEnabled true
            // shrinkResources true
            //signingConfig signingConfigs.release // When build app
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"

        }
    }

    flavorDimensions "default"
    productFlavors {
      dev {
        resValue "string", "app_name", "MyAnonymousApp_DEV"
        applicationIdSuffix ".dev"
       }

      uat {
        resValue "string", "app_name", "MyAnonymousApp_UAT"
        applicationIdSuffix ".uat"
      }

      prod {
        resValue "string", "app_name", "MyAnonymousApp"
        applicationIdSuffix ".prod"
      }
    }

    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }

        }
    }
}

dependencies {

    implementation platform('com.google.firebase:firebase-bom:28.1.0')
    implementation 'com.google.firebase:firebase-analytics'

    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.facebook.react:react-native:0.61.5"  // From node_modules
    // implementation project(':react-native-fingerprint-scanner')

    compile project(':react-native-file-viewer')

    if (enableHermes) {
        def hermesPath = "../../node_modules/hermes-engine/android/";
        debugImplementation files(hermesPath + "hermes-debug.aar")
        releaseImplementation files(hermesPath + "hermes-release.aar")
    } else {
        implementation jscFlavor
    }
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
mikehardy commented 2 years ago

Hmm - those are really old versions. I wonder what would happen if you were on current stable, or at least close to it? react-native 0.66.1 (or at least 0.65.1) with gradle 6.9 and gradle plugin 4.2.x ? Those upgrades aren't actually very hard - absolutely nothing like the jump from 0.59 to 0.60! https://react-native-community.github.io/upgrade-helper/ can help and then I bet it works

orbulant commented 2 years ago

Some extra information:

  1. File structure in android/app image The agconnect-services.json (in the screenshot above) is part of the Huawei Core Messaging Push Kit service by the way. Removing this file, will solve the issue, no more circular referencing to :app, however of course i need this file for my huawei app to work.... haha.

  2. In android/app/build.gradle, removing this line (line 2) apply plugin: "com.huawei.agconnect" will solve the issue as well.

orbulant commented 2 years ago

@mikehardy Oh very well! I will try exactly just that and report back to you kind sir.

orbulant commented 2 years ago

@mikehardy

I get the same exact problem after upgrading to Gradle 7.0 with Android Gradle Plugin 7.0.1, also tried it on Gradle 6.9.1 with Android Gradle Plugin 4.2.0

Edit: Tested with two latest verions of Android.

mikehardy commented 2 years ago

Thanks for the extra test + information, really sorry it didn't fix it!. We don't normally test with HMS services (obviously!) so I'm still not sure if this is a project setup problem or just some incompatibility. I probably won't have the time to look into this personally just yet but I can recommend two courses of action - one that is just a workaround but is stable:

1) use patch-package (https://github.com/ds300/patch-package) to make your change permanent in your repo and pretty easy to maintain (I use it all the time, I can highly recommend)

2) produce a https://stackoverflow.com/help/minimal-reproducible-example (you can start with this as a base https://github.com/mikehardy/rnfbdemo/blob/master/make-demo.sh) that only uses the modules you are using from react-native-firebase and also adds in HMS services to see if that can show the problem. It's probably okay to remove the iOS commands of course and you can probably also remove the checks for the plist/json google info files - the android build will succeed without them I think?

orbulant commented 2 years ago

@mikehardy Apologies for the late reply,

I have posted this issue to the HMS-Core GitHub as well (https://github.com/HMS-Core/hms-react-native-plugin/issues/156). From the link, as you can see someone else has this issue. Hope this helps you monitor the situation with regards to HMS compatibility.

As you mentioned, it is unsure whether or not this is a project setup problem or a compatibility issue.

For now, it seems very clearly there is some issue with Notifee in relation to Huawei's Core Messaging Service. Some things i should mention (FYI) is that on Huawei platforms, their own HMS Push plugin ( for React Native) comes with a lot more customization out of the box. To the point where there is no actual need for a great library such as Notifee to be implemented to handle notifications. The HMS Push plugin (for React Native) comes with fine grain control and of course, direct compatibility with their HMS Cloud Push Kit Service. I don't know if this knowledge is of any help, but hopefully this paints a bigger picture on why this issue is rare?, because adopting Notifee with HMS Push Plugin is a rarity (in my anecdotal opinion).

Edit: Formatting

mikehardy commented 2 years ago

For notifee there is a programmatic example builder here https://github.com/mikehardy/rnfbdemo/blob/master/notifee-demo.sh - I linked the wrong one before. Could maybe add in your yarn add <HMS-Core dep> lines there then see?

9r4ik commented 2 years ago

Yeah, same issue. to build project you need to comment 21 line in

* Where:
Build file .../node_modules/@notifee/react-native/android/build.gradle' line: 21

* What went wrong:
A problem occurred evaluating project ':notifee_react-native'.
> Circular referencing during evaluation for project ':app'.

this line

project.evaluationDependsOn(':app')

It happens when you put agconnect-services.json in android/app. If you want to build in huawei you need to comment 21 line In GMS core devices you need to remove agconnect-services.json

9r4ik commented 2 years ago

@mikehardy if you want to reproduce this issue, you can visit https://developer.huawei.com/ and register developer account and activate push kit there, then folow instruction https://developer.huawei.com/consumer/en/doc/HMS-Plugin-Guides-V1/preparedevenv-0000001050155838-V1 and put agconnect-services.json in android/app

helenaford commented 2 years ago

Is this fixed by https://github.com/invertase/notifee/pull/289?

Hesowcharov commented 1 year ago

Same issue for me...

An alternative hack may be (if you don't want to patch this package): 1) set reactNativeProjects to an empty array in order to avoid mystical project.evaluationDependsOn (I don't know for what is) in you build.gradle (root project):

// your_app/android/build.gradle
buildscript {
  ...
  ext {
    buildToolsVersion = ...
    minSdkVersion = ...
    compileSdkVersion = ...

    reactNativeProjects = []
    // ^^^ ADD THIS ^^^
  }

}

2) add explicitly an repository to resolve notifee-core in the same file:

allprojects {
  repositories {
    mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }

        google()
        jcenter()
        maven { url 'https://www.jitpack.io' }
        maven { url 'https://developer.huawei.com/repo/' }

        maven {
            url "$rootDir/../node_modules/@notifee/react-native/android/libs"
        }
        // ^^^ ADD THIS ^^^
  }
}
github-actions[bot] commented 1 year ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

moh3n9595 commented 1 year ago

Same issue

Osamasomy commented 1 year ago

same issue

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/mac/react-native/mywork/newsApp/node_modules/@notifee/react-native/android/build.gradle' line: 46
ErtugrulBEKTIK commented 1 year ago

I fixed the problem with changing the agconnect version.

buildscript {
    ...
    dependencies {
        ...
        //classpath 'com.huawei.agconnect:agcp:1.4.1.300'
        classpath 'com.huawei.agconnect:agcp:1.8.1.300'
    }
}

Also don't forget adding Huawei repo to allprojects. Because new version of React Native doesn't have allprojects section in build.gradle

allprojects {
    repositories {
        maven { url 'https://developer.huawei.com/repo/' }
    }
}
dgreasi commented 1 year ago

I facing the same issue. I don't use huawei like the rest. So obviously this is not the problem.

Dependencies

"react": "18.1.0",
"react-native": "0.70.6",
"@notifee/react-native": "^7.6.1",

Error message while trying to run in emulator or building the app:

FAILURE: Build failed with an exception.
> IDLE--------> 0% WAITING
* Where:
Build file '/Users/dimitriosgreasidis/Workspace/heycar/mobileapp/node_modules/@notif
ee/react-native/android/build.gradle' line: 46

* What went wrong:
A problem occurred evaluating project ':notifee_react-native'.
> Circular referencing during evaluation for project ':app'.

build.gradle

buildscript {
    ext {
        buildToolsVersion = "31.0.0"
        minSdkVersion = 21
        compileSdkVersion = 33
        targetSdkVersion = 33
        supportLibVersion = "28.0.0"
        kotlin_version = '1.5.21'
        if (System.properties['os.arch'] == "aarch64") {
            // For M1 Users we need to use the NDK 24 which added support for arch64
            ndkVersion = "24.0.8215888"
        } else {
            // Otherwise we default to the side-by-side NDK version from AGP.
            ndkVersion = "21.4.7075529"
        }
    }
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath('com.android.tools.build:gradle:7.2.2')
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("de.undercouch:gradle-download-task:5.0.1")
        classpath("com.bugsnag:bugsnag-android-gradle-plugin:7.+")
        classpath 'com.google.gms:google-services:4.3.10'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.firebase:perf-plugin:1.4.1'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        // Braze SDK
        maven { url "https://appboy.github.io/appboy-android-sdk/sdk" }
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }
        mavenCentral {
            // We don't want to fetch react-native from Maven Central as there are
            // older versions over there.
            content {
                excludeGroup "com.facebook.react"
            }
        }
        maven {
            // All of Detox' artifacts are provided via the npm module
            url "$rootDir/../node_modules/detox/Detox-android"
        }
        google()
        jcenter()
        maven { url 'https://www.jitpack.io' }
    }
}

Any thoughts?

UPDATE In my case the issue was the kotlin version. I updated it to v1.7.21 in my build.gradle, as you can see above, and it is working.