Rapsssito / react-native-background-actions

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

Expo managed workflow compatibility? #128

Open fobos531 opened 2 years ago

fobos531 commented 2 years ago

Hello @Rapsssito

First of all, thank you for this great library, it has really proven to be an essential part of my app!

I'm using with it with great success in my react native project (CLI project), but with Expo SDK alongside it, i.e. the bare workflow. With the advent of Expo's custom development clients and config plugins, it has been possible to use Expo's managed workflow, while also being able to use the "unsupported" libraries.

I was wondering, have you had any intentions or thoughts about supporting Expo through this workflow? I tried adding Android support on my own through a config plugin that basically does the manual configuration required by this library, but I got stuck when I actually attempted to run a background task. Basically, the task would start and at the same moment end, and I'd get a console warn saying No task registered for key: ...

Do you have any thoughts on this?

Thanks in advance!

Rapsssito commented 2 years ago

@fobos531, thanks for the feedback! I am not planning on adding support for Expo. I am not an active user of Expo and I lack the capabilities to maintain it bug-free. However, if you are finally able to set it up, I would gladly accept your PR!

contactsimonwilson commented 1 year ago

@Rapsssito what subdirectory would you like the config plugin in? I've written one for a project I'm working on and would be happy to make a PR.

Rapsssito commented 1 year ago

@contactsimonwilson, I don't know, actually. Do you know of other react-native library with the expo config plugin we can use as an example?

contactsimonwilson commented 1 year ago

Sure do. Check the plugin directory of this repo. https://github.com/includable/react-native-email-link

Rapsssito commented 1 year ago

@contactsimonwilson, okay. I don't really like the naming of "plugin". Could you create a folder named "expo" and then inside place a folder named "plugin" with the necessary code?

contactsimonwilson commented 1 year ago

@Rapsssito sure, will do.

contactsimonwilson commented 1 year ago

@Rapsssito apologies for forgetting about this. Here's a branch with my changes https://github.com/contactsimonwilson/react-native-background-actions/commit/5662a9ec5d0e63740af4c6a2b3aad2395af19402

At the moment I've published it as a standalone package. Do you want it that way or published independently or just contained within the existing package?

Rapsssito commented 1 year ago

@contactsimonwilson, whatever you prefer. If you think it will be easy to integrate with the existing package, it will probably benefit more users. However, you will have to add a notice in the README for the instructions for Expo.

contactsimonwilson commented 1 year ago

@Rapsssito will do. I'm just doing some verification of the version I've published temporarily for now then will make a PR once I'm happy it works as expected.

R4m0nz3r4 commented 1 year ago

For those using Expo managed, I end up with the following plugin. It worked just fine for me.

const { withAndroidManifest, AndroidConfig } = require("expo/config-plugins");
const { getMainApplicationOrThrow } = AndroidConfig.Manifest;

module.exports = function withBackgroundActions(config) {
    return withAndroidManifest(config, async config => {
        const application = getMainApplicationOrThrow(config.modResults);
        const service = !!application.service ? application.service : [];

        config.modResults = {
            "manifest": {
                ...config.modResults.manifest,
                "application": [{
                    ...application,
                    "service": [
                        ...service,
                        {
                            $:{
                                "android:name": "com.asterinet.react.bgactions.RNBackgroundActionsTask"
                            }
                        }
                    ]
                }]
            }
        }

        return config;
    })
}

Notice that it just adds the service tag to androids manifest. The remaining config described here can be easily add to your projects config file as referred here.

1-AlenToma commented 7 months ago

For those using Expo managed, I end up with the following plugin. It worked just fine for me.

const { withAndroidManifest, AndroidConfig } = require("expo/config-plugins");
const { getMainApplicationOrThrow } = AndroidConfig.Manifest;

module.exports = function withBackgroundActions(config) {
    return withAndroidManifest(config, async config => {
        const application = getMainApplicationOrThrow(config.modResults);
        const service = !!application.service ? application.service : [];

        config.modResults = {
            "manifest": {
                ...config.modResults.manifest,
                "application": [{
                    ...application,
                    "service": [
                        ...service,
                        {
                            $:{
                                "android:name": "com.asterinet.react.bgactions.RNBackgroundActionsTask"
                            }
                        }
                    ]
                }]
            }
        }

        return config;
    })
}

Notice that it just adds the service tag to androids manifest. The remaining config described here can be easily add to your projects config file as referred here.

I added the app.config.js but com.asterinet.react.bgactions.RNBackgroundActionsTask dose not register and get null when i try to start the service.

is there anything else to configure ?

contactsimonwilson commented 7 months ago

@1-AlenToma This is the plugin code I've been using for the last year

import { AndroidConfig, ConfigPlugin, createRunOncePlugin, withInfoPlist, withAndroidManifest, } from "@expo/config-plugins";

const pkg = { name: "react-native-background-actions", version: "UNVERSIONED" }; //require('react-native-background-actions/package.json')

/**
 * Apply background actions native configuration.
 */
const withBackgroundActions: ConfigPlugin<void> = (config) => {
  // iOS
  config = withInfoPlist(config, (newConfig) => {
    if (!newConfig.modResults.BGTaskSchedulerPermittedIdentifiers) {
      newConfig.modResults.BGTaskSchedulerPermittedIdentifiers = [];
    }

    if (
      Array.isArray(newConfig.modResults.BGTaskSchedulerPermittedIdentifiers)
    ) {
      newConfig.modResults.BGTaskSchedulerPermittedIdentifiers.push(
        "$(PRODUCT_BUNDLE_IDENTIFIER)"
      );
    }

    if (!newConfig.modResults.UIBackgroundModes) {
      newConfig.modResults.UIBackgroundModes = [];
    }

    if (
      Array.isArray(newConfig.modResults.UIBackgroundModes)
    ) {
      newConfig.modResults.UIBackgroundModes.push(
        "processing"
      );
    }

    return newConfig;
  });

  // Android
  config = AndroidConfig.Permissions.withPermissions(config, [
    "android.permission.FOREGROUND_SERVICE",
    "android.permission.WAKE_LOCK",
  ]);

  config = withAndroidManifest(config, (newConfig) => {
    if (newConfig.modResults.manifest.application) {
      if (!newConfig.modResults.manifest.application[0].service) {
        newConfig.modResults.manifest.application[0].service = [];
      }

      newConfig.modResults.manifest.application[0].service.push({
        $: {
          "android:name":
            "com.asterinet.react.bgactions.RNBackgroundActionsTask",
        },
      });
    }
    return newConfig;
  });

  return config;
};

export default createRunOncePlugin(
  withBackgroundActions,
  pkg.name,
  pkg.version
);
1-AlenToma commented 7 months ago

@contactsimonwilson

I think I found the issue, I am developing this on my phone with termux and are not able to run:android command so the autolink is not working.

I run expo prebuild only but it is not helpng, will test the code above any way thx

yoryi commented 3 months ago

Quien puede darme ayuda con un plugin para expo?