Rapsssito / react-native-background-actions

React Native background service library for running background tasks forever in Android & iOS.
MIT License
814 stars 116 forks source link

Task started but not running on Android (OK on iOS) #239

Open adriendomoison opened 1 month ago

adriendomoison commented 1 month ago

Hi, I'm running into an issue on Android only. The app shows no signs of errors on the JS side. The background notification shows and remains displayed indefinitely in the notification bar, but nothing happens, the task function is never called.

await BackgroundService.start(
  async () => {
    console.log('I am never called'); // never printed
  },
  {
    taskName: 'Sending Message',
    taskTitle: 'Sending Message',
    taskDesc: 'Sending Message',
    taskIcon: {
      name: 'ic_launcher',
      type: 'mipmap',
    },
  },
);
console.log(
  'Background service is running > ', BackgroundService.isRunning(),
); // print "Background service is running > true"

Android Studio does give me an error when the background service is started however.

Logcat ``` E Exception in native call from JS com.facebook.react.common.JavascriptException: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime, stack: Error: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime at queueMicrotask (native) at anonymous (http://localhost:8081/index.bundle/:347048:25) at anonymous (http://localhost:8081/index.bundle/:397427:7) at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14) at guardedLoadModule (http://localhost:8081/index.bundle/:176:38) at metroRequire (http://localhost:8081/index.bundle/:90:92) at anonymous (http://localhost:8081/index.bundle/:396674:62) at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14) at guardedLoadModule (http://localhost:8081/index.bundle/:176:38) at metroRequire (http://localhost:8081/index.bundle/:90:92) at anonymous (http://localhost:8081/index.bundle/:396612:58) at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14) at guardedLoadModule (http://localhost:8081/index.bundle/:176:38) at metroRequire (http://localhost:8081/index.bundle/:90:92) at anonymous (http://localhost:8081/index.bundle/:396546:46) at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14) at guardedLoadModule (http://localhost:8081/index.bundle/:176:38) at metroRequire (http://localhost:8081/index.bundle/:90:92) at anonymous (http://localhost:8081/index.bundle/:396056:62) at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14) at guardedLoadModule (http://localhost:8081/index.bundle/:176:38) at metroRequire (http://localhost:8081/index.bundle/:90:92) Attempting to call JS function on a bad application bundle: HMRClient.setup() Exception in native call java.lang.RuntimeException: Attempting to call JS function on a bad application bundle: HMRClient.setup() at com.facebook.jni.NativeRunnable.run(Native Method) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:235) at java.lang.Thread.run(Thread.java:920) Attempting to call JS function on a bad application bundle: AppRegistry.startHeadlessTask() Unable to launch redbox because react activity is not available, here is the error that redbox would've displayed: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime, stack: Error: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime at queueMicrotask (native) at anonymous (http://localhost:8081/index.bundle/:347048:25) at anonymous (http://localhost:8081/index.bundle/:397427:7) at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14) at guardedLoadModule (http://localhost:8081/index.bundle/:176:38) at metroRequire (http://localhost:8081/index.bundle/:90:92) at anonymous (http://localhost:8081/index.bundle/:396674:62) at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14) at guardedLoadModule (http://localhost:8081/index.bundle/:176:38) at metroRequire (http://localhost:8081/index.bundle/:90:92) Exception in native call java.lang.RuntimeException: Attempting to call JS function on a bad application bundle: RCTDeviceEventEmitter.emit() at com.facebook.jni.NativeRunnable.run(Native Method) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:235) at java.lang.Thread.run(Thread.java:920) Unable to launch redbox because react activity is not available, here is the error that redbox would've displayed: Attempting to call JS function on a bad application bundle: AppRegistry.startHeadlessTask() Attempting to call JS function on a bad application bundle: RCTDeviceEventEmitter.emit() UIManagerBinding::~UIManagerBinding() was called CatalystInstanceImpl.destroy() end ```

I did set up the AndroidManifest.xml according to the documentation (adding permissions and service)

The app is running on react-native@0.75.3 and react-native-background-actions@4.0.1

build.gradle ``` apply plugin: "com.android.application" apply plugin: "org.jetbrains.kotlin.android" apply plugin: "com.facebook.react" apply plugin: 'com.google.gms.google-services' def getPassword(String currentUser, String keyChain) { def stdout = new ByteArrayOutputStream() def stderr = new ByteArrayOutputStream() exec { commandLine 'security', '-q', 'find-generic-password', '-a', currentUser, '-s', keyChain, '-w' standardOutput = stdout errorOutput = stderr ignoreExitValue true } stdout.toString().trim() } react { /* Autolinking */ autolinkLibrariesWithApp() // Added by install-expo-modules entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", rootDir.getAbsoluteFile().getParentFile().getAbsolutePath(), "android", "absolute"].execute(null, rootDir).text.trim()) cliFile = new File(["node", "--print", "require.resolve('@expo/cli')"].execute(null, rootDir).text.trim()) bundleCommand = "export:embed" } def enableProguardInReleaseBuilds = false def jscFlavor = 'org.webkit:android-jsc:+' def pass = getPassword("adomoison@gmail.com", "android_keystore") android { ndkVersion rootProject.ext.ndkVersion buildToolsVersion rootProject.ext.buildToolsVersion compileSdk rootProject.ext.compileSdkVersion namespace "app.app.app" defaultConfig { applicationId "app.app.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 10 versionName "0.3.15" } signingConfigs { 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 pass keyAlias MYAPP_UPLOAD_KEY_ALIAS keyPassword pass } } } buildTypes { debug { signingConfig signingConfigs.debug } release { // Caution! In production, you need to generate your own keystore file. // see https://reactnative.dev/docs/signed-apk-android. signingConfig signingConfigs.release minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } } dependencies { implementation("com.facebook.react:react-android") if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") } else { implementation jscFlavor } } ```
MainApplication.kt ``` package app.app.app import android.content.res.Configuration import expo.modules.ApplicationLifecycleDispatcher import expo.modules.ReactNativeHostWrapper import android.app.Application import com.facebook.react.PackageList import com.facebook.react.ReactApplication import com.facebook.react.ReactHost import com.facebook.react.ReactNativeHost import com.facebook.react.ReactPackage import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost import com.facebook.react.defaults.DefaultReactNativeHost import com.facebook.soloader.SoLoader class MainApplication : Application(), ReactApplication { override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(this, object : DefaultReactNativeHost(this) { override fun getPackages(): List = PackageList(this).packages.apply { // Packages that cannot be autolinked yet can be added manually here, for example: // add(MyReactNativePackage()) } override fun getJSMainModuleName(): String = "index" override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED }) override val reactHost: ReactHost get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost) override fun onCreate() { super.onCreate() SoLoader.init(this, false) if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { // If you opted-in for the New Architecture, we load the native entry point for this app. load() } ApplicationLifecycleDispatcher.onApplicationCreate(this) } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig) } } ```

Any insights would be greatly appreciated. Thank you!

somasekharkakarla commented 1 month ago

can you please the steps for ios. My android is running but not ios.

ravindraguptacapgemini commented 2 weeks ago

It's not starting for me at all in Android, any solutions yet? The app is running on react-native@0.75.3 and react-native-background-actions@4.0.1

adriendomoison commented 1 week ago

Switching newArchEnabled=true to newArchEnabled=false in android/gradle.properties allowed the started task to actually run.

I'm not sure if this needs to be documented or if it already exists somewhere I could not find?

tohel17 commented 1 week ago

@adriendomoison I am facing the same issue it's working fine on iOS with newArchEnabled but in android it fails, Is there any fix to work with newArchEnabled?

shovel-kun commented 1 week ago

@tohel17

AFAIK, you need to wait for RN 0.76.1 (coming in a few days) for the library to work on New Arch.

Source: https://github.com/invertase/react-native-firebase/issues/8091#issuecomment-2440499904

ravindraguptacapgemini commented 1 week ago

@tohel17 what about the fix in 0.75.x version?

tohel17 commented 1 week ago

I am on 0.75.4 still same issues. Looks like you have to wait for 0.76.1

adriendomoison commented 1 week ago

To add some more info, a good amount of other packages do not work yet with 0.76.x and it could take several extra weeks for maintainers to deliver the required updates.

Depending on how many dependencies you have in your current project and how much you are using the newArch already, it could be easier to just stay on 0.75.x and disable newArch.

The decision will highly depends on your circumstances ✌️

tohel17 commented 5 days ago

It works fine with latest version of RN 0.76.3 with new architecture enabled.

ravindraguptacapgemini commented 4 days ago

Can we expect it to start working with any RN 0.75.x release?

tohel17 commented 4 days ago

@ravindraguptacapgemini Since the issue was on RN side either you have to update to 0.76.1 or use old architecture on 0.75.x version.

ravindraguptacapgemini commented 4 days ago

I don't see newer react native version under releases https://github.com/facebook/react-native/releases