notifee icon indicating copy to clipboard operation
notifee copied to clipboard

Expo SDK 49 compatibility issue

Open Thanaen opened this issue 1 year ago • 51 comments

Hello,

The first beta of the Expo 49 SDK has just been released, and I wanted to compile my application with it to see if it worked. I've only tried it on Android for the moment, and I'm getting this error:

Could not determine the dependencies of task ':app:lintVitalReportRelease'.
> Could not resolve all task dependencies for configuration ':app:releaseRuntimeClasspath'.
   > Could not find any matches for app.notifee:core:+ as no versions of app.notifee:core are available.
     Searched in the following locations:
       - file:/Users/user/Desktop/Dev/app-name/node_modules/react-native/android/app/notifee/core/maven-metadata.xml
       - file:/Users/user/Desktop/Dev/app-name/node_modules/jsc-android/dist/app/notifee/core/maven-metadata.xml
       - https://dl.google.com/dl/android/maven2/app/notifee/core/maven-metadata.xml
       - https://repo.maven.apache.org/maven2/app/notifee/core/maven-metadata.xml
       - https://www.jitpack.io/app/notifee/core/maven-metadata.xml
       - https://oss.sonatype.org/content/repositories/snapshots/app/notifee/core/maven-metadata.xml
     Required by:
         project :app > project :notifee_react-native

I'm thinking it might be linked to the switch to gradle 8.

Nothing urgent, since SDK 49 is only in beta, but I thought I'd give you a heads-up. :)

Thanaen avatar Jun 29 '23 14:06 Thanaen

Hey there - could be - I haven't tested notifee with rn72 / gradle 8 yet, but we do a little magic here to add our compiled AAR android library (which is in a local maven repository) to the set of maven repositories in the project.

I think this is it

https://github.com/invertase/notifee/blob/main/packages/react-native/android/build.gradle https://github.com/invertase/notifee/blob/94cb4bc16e835f815fd97fa3c0263afc4ebf5524/packages/react-native/android/build.gradle#L107-L112

Perhaps that's failing now...

mikehardy avatar Jun 29 '23 15:06 mikehardy

Just to let you know, Expo's SDK 49 has just been released from beta!

PS: I'm not saying this to be pushy or anything, it's just to keep the context of this issue up to date.

Thanaen avatar Jul 05 '23 22:07 Thanaen

Facing the same issue as well after upgrading to Expo 49

Could not determine the dependencies of task ':app:processDebugResources'.
> Could not resolve all task dependencies for configuration ':app:debugRuntimeClasspath'.
   > Could not find any matches for app.notifee:core:+ as no versions of app.notifee:core are available.
     Searched in the following locations:
       - file:/C:/Users/d11dev/GitHub/ProjectName/node_modules/react-native/android/app/notifee/core/maven-metadata.xml
       - file:/C:/Users/d11dev/GitHub/ProjectName/node_modules/jsc-android/dist/app/notifee/core/maven-metadata.xml
       - file:/C:/Users/d11dev/GitHub/ProjectName/apps/node_modules/@notifee/react-native/android/libs/app/notifee/core/maven-metadata.xml
       - https://dl.google.com/dl/android/maven2/app/notifee/core/maven-metadata.xml
       - https://repo.maven.apache.org/maven2/app/notifee/core/maven-metadata.xml
       - https://www.jitpack.io/app/notifee/core/maven-metadata.xml
       - https://oss.sonatype.org/content/repositories/snapshots/app/notifee/core/maven-metadata.xml
     Required by:
         project :app > project :notifee_react-native

Additional context, this is a monorepo

d11dev avatar Jul 06 '23 13:07 d11dev

Facing the same issue as well after upgrading to Expo 49

....

Following up on this, I was able to temporarily fix the issue with this config code (very rough):

import {
  ConfigPlugin,
  withPlugins,
  withProjectBuildGradle,
  WarningAggregator,
} from "@expo/config-plugins";

import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";

const MODULE_NAME = "rn-project-build-gradle";

const notifeeImport = `import java.nio.file.Paths`;

const notifeeFindNodeModulePath = `
def findNodeModulePath(baseDir, packageName) {
  def basePath = baseDir.toPath().normalize()
  // Node's module resolution algorithm searches up to the root directory,
  // after which the base path will be null
  while (basePath) {
    def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
    if (candidatePath.toFile().exists()) {
      return candidatePath.toString()
    }
    basePath = basePath.getParent()
  }
  return null
}

def notifeeDir = findNodeModulePath(projectDir, "@notifee/react-native") ?: "$rootDir/../node_modules/@notifee/react-native"`;

const notifeeCoreMavenUrl = `maven {
          url "$notifeeDir/android/libs"
        }
        google()`;

const androidPlugin: ConfigPlugin<Map<string, string | boolean>> = (
  config,
  props,
) => {
  return withProjectBuildGradle(
    config,
    async ({ modResults, ...subConfig }) => {
      if (modResults.language !== "groovy") {
        WarningAggregator.addWarningAndroid(
          "withExpoProjectGradle",
          `Cannot automatically configure project build.gradle if it's not groovy`,
        );
        return { modResults, ...subConfig };
      }

      // notifeeImport
      modResults.contents = await applyGradleMod(
        modResults.contents,
        notifeeImport,
        /buildscript(?:\s+)?\{/,
        true,
        0,
      );

      // notifeeFindNodeModulePath
      modResults.contents = await applyGradleMod(
        modResults.contents,
        notifeeFindNodeModulePath,
        /allprojects(?:\s+)?\{/,
        true,
        1,
      );

      // notifeeCoreMavenUrl
      const regex =
        /(?<=allprojects\s*{[\s\S]*repositories\s*{[\s\S]*?)google\(\)/g;
      modResults.contents = modResults.contents.replace(
        regex,
        notifeeCoreMavenUrl,
      );

      return { modResults, ...subConfig };
    },
  );
};

const withExpoProjectGradle: ConfigPlugin<{} | void> = (config, _props) => {
  const props = _props || {};

  return withPlugins(config, [
    [androidPlugin, new Map<string, string | boolean>(Object.entries(props))],
  ]);
};

const applyGradleMod = async (
  buildGradle: string,
  code: string,
  anchorRegex: string | RegExp,
  insertAbove: boolean = false,
  tagNumber: Number = 0,
) => {
  try {
    return mergeContents({
      // Tag needs to be unique so that previous mod does not get deleted
      tag: `${MODULE_NAME}_${tagNumber}`,
      src: buildGradle,
      newSrc: code,
      anchor: anchorRegex,
      // new line will be inserted right above matched anchor when 0
      offset: insertAbove ? 0 : 1,
      comment: "//",
    }).contents;
  } catch (e) {
    console.error(e);
    return buildGradle;
  }
};

export default withExpoProjectGradle;

Seems like rootProject.allProjects is not working correctly Gradle 8+ or might be another issue

d11dev avatar Jul 06 '23 19:07 d11dev

Wow, that's a hardcore plugin! I'm going to give this a quick try. Thanks for the workaround!

Thanaen avatar Jul 07 '23 08:07 Thanaen

I have the same issue trying to install the app on SDK 49. I unfortunately can't take the path of downgrading to SDK 48, I hope this can be resolved easily....

UltraWelfare avatar Jul 12 '23 12:07 UltraWelfare

Have you tried using the plugin made by @d11dev? It works fine for me!

Thanaen avatar Jul 12 '23 12:07 Thanaen

Yeah I'm on my way exploring on how to add config code like this. However an official solution would be preferred, you never know what other bugs may surface, especially in production code. I would definitely give it a try though, thanks for the solution!

For anyone curious how to add the config code, you can look at this documentation here

UltraWelfare avatar Jul 12 '23 13:07 UltraWelfare

Facing the same issue as well after upgrading to Expo 49 ....

Following up on this, I was able to temporarily fix the issue with this config code (very rough):

import {
  ConfigPlugin,
  withPlugins,
  withProjectBuildGradle,
  WarningAggregator,
} from "@expo/config-plugins";

import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";

const MODULE_NAME = "rn-project-build-gradle";

const notifeeImport = `import java.nio.file.Paths`;

const notifeeFindNodeModulePath = `
def findNodeModulePath(baseDir, packageName) {
  def basePath = baseDir.toPath().normalize()
  // Node's module resolution algorithm searches up to the root directory,
  // after which the base path will be null
  while (basePath) {
    def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
    if (candidatePath.toFile().exists()) {
      return candidatePath.toString()
    }
    basePath = basePath.getParent()
  }
  return null
}

def notifeeDir = findNodeModulePath(projectDir, "@notifee/react-native") ?: "$rootDir/../node_modules/@notifee/react-native"`;

const notifeeCoreMavenUrl = `maven {
          url "$notifeeDir/android/libs"
        }
        google()`;

const androidPlugin: ConfigPlugin<Map<string, string | boolean>> = (
  config,
  props,
) => {
  return withProjectBuildGradle(
    config,
    async ({ modResults, ...subConfig }) => {
      if (modResults.language !== "groovy") {
        WarningAggregator.addWarningAndroid(
          "withExpoProjectGradle",
          `Cannot automatically configure project build.gradle if it's not groovy`,
        );
        return { modResults, ...subConfig };
      }

      // notifeeImport
      modResults.contents = await applyGradleMod(
        modResults.contents,
        notifeeImport,
        /buildscript(?:\s+)?\{/,
        true,
        0,
      );

      // notifeeFindNodeModulePath
      modResults.contents = await applyGradleMod(
        modResults.contents,
        notifeeFindNodeModulePath,
        /allprojects(?:\s+)?\{/,
        true,
        1,
      );

      // notifeeCoreMavenUrl
      const regex =
        /(?<=allprojects\s*{[\s\S]*repositories\s*{[\s\S]*?)google\(\)/g;
      modResults.contents = modResults.contents.replace(
        regex,
        notifeeCoreMavenUrl,
      );

      return { modResults, ...subConfig };
    },
  );
};

const withExpoProjectGradle: ConfigPlugin<{} | void> = (config, _props) => {
  const props = _props || {};

  return withPlugins(config, [
    [androidPlugin, new Map<string, string | boolean>(Object.entries(props))],
  ]);
};

const applyGradleMod = async (
  buildGradle: string,
  code: string,
  anchorRegex: string | RegExp,
  insertAbove: boolean = false,
  tagNumber: Number = 0,
) => {
  try {
    return mergeContents({
      // Tag needs to be unique so that previous mod does not get deleted
      tag: `${MODULE_NAME}_${tagNumber}`,
      src: buildGradle,
      newSrc: code,
      anchor: anchorRegex,
      // new line will be inserted right above matched anchor when 0
      offset: insertAbove ? 0 : 1,
      comment: "//",
    }).contents;
  } catch (e) {
    console.error(e);
    return buildGradle;
  }
};

export default withExpoProjectGradle;

Seems like rootProject.allProjects is not working correctly Gradle 8+ or might be another issue

Hello, would be also awesome if you could share the generated code inside "build" -directory, so would not need to setup module project to get generated code. As I would use the generated code inside my main apps plugin directory instead separate plugin.

simonitfi avatar Jul 19 '23 08:07 simonitfi

So I managed this, and here if some one is interested:

  1. On main project add new folder on root called "plugin" if you don't already have.

  2. On plugin-folder add file named "notifee-fix-plugin.js" with following content: module.exports = require('./notifee-fix-files/withExpoProjectGradle')

  3. Create new folder inside plugin folder called "notifee-fix-files" and add following two files on that folder: "withExpoProjectGradle.d.ts" with content

import { ConfigPlugin } from "@expo/config-plugins"; declare const withExpoProjectGradle: ConfigPlugin<{} | void>; export default withExpoProjectGradle;

and file called "withExpoProjectGradle.js" with following content:

"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const config_plugins_1 = require("@expo/config-plugins"); const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode"); const MODULE_NAME = "rn-project-build-gradle"; const notifeeImport = import java.nio.file.Paths; const notifeeFindNodeModulePath = def findNodeModulePath(baseDir, packageName) { def basePath = baseDir.toPath().normalize() // Node's module resolution algorithm searches up to the root directory, // after which the base path will be null while (basePath) { def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName) if (candidatePath.toFile().exists()) { return candidatePath.toString() } basePath = basePath.getParent() } return null }

def notifeeDir = findNodeModulePath(projectDir, "@notifee/react-native") ?: "$rootDir/../node_modules/@notifee/react-native"; const notifeeCoreMavenUrl = maven { url "$notifeeDir/android/libs" } google(); const androidPlugin = (config, props) => { return (0, config_plugins_1.withProjectBuildGradle)(config, async ({ modResults, ...subConfig }) => { if (modResults.language !== "groovy") { config_plugins_1.WarningAggregator.addWarningAndroid("withExpoProjectGradle", Cannot automatically configure project build.gradle if it's not groovy); return { modResults, ...subConfig }; } // notifeeImport modResults.contents = await applyGradleMod(modResults.contents, notifeeImport, /buildscript(?:\s+)?\{/, true, 0); // notifeeFindNodeModulePath modResults.contents = await applyGradleMod(modResults.contents, notifeeFindNodeModulePath, /allprojects(?:\s+)?\{/, true, 1); // notifeeCoreMavenUrl const regex = /(?<=allprojects\s*{[\s\S]*repositories\s*{[\s\S]*?)google\(\)/g; modResults.contents = modResults.contents.replace(regex, notifeeCoreMavenUrl); return { modResults, ...subConfig }; }); }; const withExpoProjectGradle = (config, _props) => { const props = _props || {}; return (0, config_plugins_1.withPlugins)(config, [ [androidPlugin, new Map(Object.entries(props))], ]); }; const applyGradleMod = async (buildGradle, code, anchorRegex, insertAbove = false, tagNumber = 0) => { try { return (0, generateCode_1.mergeContents)({ // Tag needs to be unique so that previous mod does not get deleted tag: ${MODULE_NAME}_${tagNumber}, src: buildGradle, newSrc: code, anchor: anchorRegex, // new line will be inserted right above matched anchor when 0 offset: insertAbove ? 0 : 1, comment: "//", }).contents; } catch (e) { console.error(e); return buildGradle; } }; exports.default = withExpoProjectGradle;

  1. Finally add add plugin to app.json "plugins": [ "./plugins/notifee-fix-plugin" ]

simonitfi avatar Jul 19 '23 09:07 simonitfi

Or you can just use expo-build-properties as follows:

const config = {
  expo: {
    // ...
    plugins: [
      [
        'expo-build-properties',
        {
          android: {
            extraMavenRepos: ['$rootDir/../../../node_modules/@notifee/react-native/android/libs'],
          }
        },
      ],
    ],
  },
};

Since my app is a monorepo configuration, the exact path may be different, but anyone can find the correct path by referring to the error message.

mu29 avatar Jul 21 '23 02:07 mu29

Or you can just use expo-build-properties as follows:

const config = {
  expo: {
    // ...
    plugins: [
      [
        'expo-build-properties',
        {
          android: {
            extraMavenRepos: ['$rootDir/../../../node_modules/@notifee/react-native/android/libs'],
          }
        },
      ],
    ],
  },
};

Since my app is a monorepo configuration, the exact path may be different, but anyone can find the correct path by referring to the error message.

This worked for me 👍

cgorrieri avatar Jul 22 '23 21:07 cgorrieri

Or you can just use expo-build-properties as follows:

const config = {
  expo: {
    // ...
    plugins: [
      [
        'expo-build-properties',
        {
          android: {
            extraMavenRepos: ['$rootDir/../../../node_modules/@notifee/react-native/android/libs'],
          }
        },
      ],
    ],
  },
};

Since my app is a monorepo configuration, the exact path may be different, but anyone can find the correct path by referring to the error message.

did not work for me on fresh install

frozencap avatar Jul 25 '23 23:07 frozencap

Or you can just use expo-build-properties as follows:

const config = {
  expo: {
    // ...
    plugins: [
      [
        'expo-build-properties',
        {
          android: {
            extraMavenRepos: ['$rootDir/../../../node_modules/@notifee/react-native/android/libs'],
          }
        },
      ],
    ],
  },
};

Since my app is a monorepo configuration, the exact path may be different, but anyone can find the correct path by referring to the error message.

did not work for me on fresh install

Try to run in verbose mode so it shows you the paths it is looking into for the maven repos. It is possible that the $rootDir/../../../node_modules might need some adjustments for your setup.

cgorrieri avatar Jul 26 '23 07:07 cgorrieri

it did work, had the wrong path. for those not in a monorepo, this is likely the path you're looking for

          android: {
            extraMavenRepos: [
              '../../node_modules/@notifee/react-native/android/libs',
            ],
          },

that being said, build times have more than doubled 😕

expected?

frozencap avatar Jul 27 '23 21:07 frozencap

Or you can just use expo-build-properties as follows:

const config = {
  expo: {
    // ...
    plugins: [
      [
        'expo-build-properties',
        {
          android: {
            extraMavenRepos: ['$rootDir/../../../node_modules/@notifee/react-native/android/libs'],
          }
        },
      ],
    ],
  },
};

Since my app is a monorepo configuration, the exact path may be different, but anyone can find the correct path by referring to the error message.

Works for me tks 💪 But I edited the path to ../../node_modules/@notifee/react-native/android/libs

netorissi avatar Aug 05 '23 13:08 netorissi

It happened to me as well since I updated my Expo SDK to 49. Is anyone have a good solution for this? Thanks in advance.

harisnaufal avatar Aug 16 '23 10:08 harisnaufal

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.

github-actions[bot] avatar Sep 13 '23 10:09 github-actions[bot]

The issue is not stale, it's still relevant

Thanaen avatar Sep 13 '23 12:09 Thanaen

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.

github-actions[bot] avatar Oct 11 '23 12:10 github-actions[bot]

This issue is still relevant.

Iannery avatar Oct 11 '23 13:10 Iannery

I'm afraid that the maintainers of this library no longer have the time to spend on it 😅 Maybe it's time to turn to Expo Notifications (even though I preferred the Notifee API).

Note: this is of course not a criticism of the maintainers, who give a lot of their time to open source projects!

Thanaen avatar Oct 11 '23 13:10 Thanaen

@Thanaen not true: https://github.com/invertase/notifee/issues/899#issuecomment-1786199159

younes0 avatar Nov 08 '23 04:11 younes0

Thanks @younes0 and no offense taken @Thanaen - I do have plans on getting this repo all polished up in the short-term and Invertase in the medium- long-term has and does benevolently provide resources to do so

Still finishing up some urgent work in other repos to get things prepared for react-native 0.73 which is about to launch and requires some changes all over

mikehardy avatar Nov 08 '23 04:11 mikehardy

@shawarmaz the build times haven't changed on my side

younes0 avatar Nov 08 '23 06:11 younes0

@younes0 This seemed to be the case when I wrote this comment 28 days ago. 😄

@mikehardy Glad to hear you'll be able to spend some time on the project in the short term!

I was wondering, have you ever considered adding maintainers from outside Invertase to the project?

I've recently seen some authors of open source projects turn to solutions like https://polar.sh/ to fund the resolution of issues that would be considered important, do you think that this, combined with the addition of external contributors, could help you keep the project active in the longer term?

Thanaen avatar Nov 08 '23 08:11 Thanaen

Or you can just use expo-build-properties as follows:

const config = {
  expo: {
    // ...
    plugins: [
      [
        'expo-build-properties',
        {
          android: {
            extraMavenRepos: ['$rootDir/../../../node_modules/@notifee/react-native/android/libs'],
          }
        },
      ],
    ],
  },
};

Since my app is a monorepo configuration, the exact path may be different, but anyone can find the correct path by referring to the error message.

This also worked for me, just one thing, I'm using Solito and this is the path that worked for me:

$rootDir/../../../../../node_modules/@notifee/react-native/android/libs

edwinvrgs avatar Nov 14 '23 15:11 edwinvrgs

Or you can just use expo-build-properties as follows:

const config = {
  expo: {
    // ...
    plugins: [
      [
        'expo-build-properties',
        {
          android: {
            extraMavenRepos: ['$rootDir/../../../node_modules/@notifee/react-native/android/libs'],
          }
        },
      ],
    ],
  },
};

Since my app is a monorepo configuration, the exact path may be different, but anyone can find the correct path by referring to the error message.

This also worked for me, just one thing, I'm using Solito and this is the path that worked for me:

$rootDir/../../../../../node_modules/@notifee/react-native/android/libs

where should i put this code in ?

omarhamedx avatar Nov 15 '23 17:11 omarhamedx

@omarhamedx in the app.json or app.config.js. And remember to regenerate the android folder (you can do it by executing npx expo prebuild --clean).

edwinvrgs avatar Nov 15 '23 18:11 edwinvrgs

@omarhamedx the solution was already provided, please ask on Stack Overflow. Everytime someone ask for support on an issue that people/contributors follow, they get an email so imagine the spamming

younes0 avatar Nov 15 '23 23:11 younes0