Raja0sama / rn-foreground-service

Foreground Service for React Native made with ❤
https://rn-foreground.vercel.app/
147 stars 70 forks source link

new NativeEventEmitter() requires a non-null argument #107

Open akankshaingle opened 1 month ago

akankshaingle commented 1 month ago

I am encountering an error when trying to register the foreground service using ReactNativeForegroundService from the @supersami/rn-foreground-service library. The same code works correctly on Android, but I am facing issues on iOS.

Screenshot 2024-09-25 at 3 53 58 PM

Code:

import ReactNativeForegroundService from "@supersami/rn-foreground-service";

const config = {
  config: {
    alert: true,
    onServiceErrorCallBack: function () {
      console.warn('[ReactNativeForegroundService] onServiceErrorCallBack', arguments);
    },
  }
};

ReactNativeForegroundService.register(config);

Error:

ERROR  Invariant Violation: `new NativeEventEmitter()` requires a non-null argument., js engine: hermes
WARN  Module ReactNativeEventEmitter requires main queue setup since it overrides `init` but doesn't implement `requiresMainQueueSetup`. In a future release React Native will default to initializing all native modules on a background thread unless explicitly opted-out of.
LOG  Running "Cerge" with {"rootTag":21,"initialProps":{}}

Environment:

React Native version: "0.71.19" Library version: "^2.1.1" JS Engine: Hermes Platform: iOS

Steps to Reproduce:

Install the @supersami/rn-foreground-service library. Use the ReactNativeForegroundService.register(config) method in the code as shown above. Run the app on iOS with Hermes enabled.

Expected Behavior: The service should register without errors.

Actual Behavior: The error new NativeEventEmitter() requires a non-null argument occurs, and the warning about requiresMainQueueSetup appears.

Additional Context: This issue appears to be related to how the NativeEventEmitter is being initialized with a null or undefined argument. The warning suggests the module may need to implement requiresMainQueueSetup.

Raja0sama commented 1 month ago

Investigating, make sure you are initializing the app in the very start of the application. Please refer to this example application

https://github.com/Raja0sama/rn-forground-service-example

akankshaingle commented 1 month ago

Investigating, make sure you are initializing the app in the very start of the application. Please refer to this example application

https://github.com/Raja0sama/rn-forground-service-example

@Raja0sama, I tried registering the service in my main index.js file, but it didn't work for me.

Raja0sama commented 1 month ago

Are using expo ?>

akankshaingle commented 1 month ago

Are using expo ?>

No, Using React Native CLI

Raja0sama commented 1 month ago

Please use this as a reference, if the implementation of this is working for you that means something is off with the configuration of your project. Just clone it and test.

akankshaingle commented 1 month ago

@Raja0sama, I'm encountering the same issue even with the cloned repository: https://github.com/Raja0sama/rn-forground-service-example

Sanjaya94 commented 1 month ago

I'm encountering the same issue on IOS, Android works fine.

react-native: "0.74.5" @supersami/rn-foreground-service: "^2.1.1"

Iphone 16 pro max / IOS 18

Sanjaya94 commented 1 month ago

I found a solution. Edit : node_modules/@supersami/rn-foreground-service/index.js

  1. Modify the NativeEventEmitter instantiation to handle null

import { NativeModules, AppRegistry, DeviceEventEmitter, NativeEventEmitter, Alert, Platform, } from 'react-native';

const ForegroundServiceModule = Platform.OS === 'android' ? NativeModules.ForegroundService : null;

const eventEmitter = ForegroundServiceModule ? new NativeEventEmitter(ForegroundServiceModule) : null;

export function setupServiceErrorListener({ onServiceFailToStart, alert }) { if (!eventEmitter) { console.warn('ForegroundServiceModule is not available'); return; }

const listener = eventEmitter.addListener('onServiceError', message => { if (alert) { Alert.alert('Service Error', message); } if (onServiceFailToStart) { onServiceFailToStart(); } stop(); });

return () => { listener.remove(); }; }

  1. Ensure that event listeners are only registered if the module is available const eventListener = callBack => { if (!ForegroundServiceModule) { console.warn('ForegroundServiceModule is not available'); return () => {}; }

    let subscription = DeviceEventEmitter.addListener( 'notificationClickHandle', callBack, );

    return function cleanup() { subscription.remove(); }; };

akankshaingle commented 1 month ago

I resolved the issue by importing the @supersami/rn-foreground-service library conditionally based on the platform. This way, it only initializes on Android and avoids issues on iOS:

let ReactNativeForegroundService;
if (Platform.OS === 'android') {
  ReactNativeForegroundService = require('@supersami/rn-foreground-service').default;
} else {
  ReactNativeForegroundService = null;
}
ganeshtak19 commented 1 month ago

After using above solution , the service is not starting, i am getting this eror ReactNativeForegroundService.start({ id: 1244, title: 'Live Tracking', message: 'Live tracking', icon: 'ic_launcher', button: false, button2: false, buttonText: '', button2Text: '', buttonOnPress: '', // setOnlyAlertOnce: true, color: '#000000', }) .then(res => { console.log('foreground service started', res) }) .catch((error: any) => { console.log('foreground service error', error) }) [Error: ForegroundService: ServiceType is required]

akankshaingle commented 1 month ago

After using above solution , the service is not starting, i am getting this eror ReactNativeForegroundService.start({ id: 1244, title: 'Live Tracking', message: 'Live tracking', icon: 'ic_launcher', button: false, button2: false, buttonText: '', button2Text: '', buttonOnPress: '', // setOnlyAlertOnce: true, color: '#000000', }) .then(res => { console.log('foreground service started', res) }) .catch((error: any) => { console.log('foreground service error', error) }) [Error: ForegroundService: ServiceType is required]

@ganeshtak19, You can resolve this by adding the serviceType property to your start method, like this:

ReactNativeForegroundService.start({
    id: 144,
    title: 'Beacon Detection',
    message: 'Detecting nearby beacons',
    visibility: 'public',
    importance: 'low',
    icon: 'ic_launcher',
    channelId: 'myapp_notification',
    serviceType: 'location', // Add this line
});

Additionally, make sure to update the library's type definition file to include the serviceType prop in the start method. You can do this by editing the following file:

node_modules/@supersami/rn-foreground-service/index.d.ts

Add the serviceType property to the type definition for the start method

Screenshot 2024-10-10 at 2 29 37 PM