eddieowens / react-native-boundary

Native implementation of geofencing/region monitoring
Apache License 2.0
121 stars 72 forks source link

Event callbacks not firing when app is killed: Sending `onExit` with no listeners registered. #33

Open ValentinBlokhin opened 5 years ago

ValentinBlokhin commented 5 years ago

Awesome library, but trying to get it work when app is killed. It actually starts app on boundary change, but I have Sending onExit with no listeners registered. Is it supposed to work when app is killed? I'm using ios.

eddieowens commented 5 years ago

Hey @ValentinBlokhin, what version of the lib are you using?

ValentinBlokhin commented 5 years ago

Hey @eddieowens , I've been using 1.1.0 version.

eddieowens commented 5 years ago

@ValentinBlokhin Can you post the relevant code block?

chrisspankroy commented 5 years ago

Is there something special I need to do to get it to work when the app is killed? I can't find any documentation about it

mikaelengstrom commented 5 years ago

I am having similar issues when killed. Could it be that the event listeners is bound in such a way that when the app is waked up on geofencing-events that registration of listeners is simply not run (or run after the event is emitted). I have little experience around what code actually gets called when wake up happens in a react-native context. Does anyone know or have a good resource around the topic?

gusilveiramp commented 4 years ago

Same here. Everything works perfect on Android and iOS, but if the app is Killed on iOS and some transition is detected, when i open the app it show's this warning: warning-error

My code looks exactly like the repository example.

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

const {RNBoundary} = NativeModules;

const TAG = "RNBoundary";

const boundaryEventEmitter = new NativeEventEmitter(RNBoundary);

const Events = {
  EXIT: "onExit",
  ENTER: "onEnter",
};

export { Events }

const HeadlessBoundaryEventTask = async ({event, ids}) => {
  console.log(event, ids);
  boundaryEventEmitter.emit(event, ids)
};

AppRegistry.registerHeadlessTask('OnBoundaryEvent', () => HeadlessBoundaryEventTask);

export default {
  add: boundary => {
    if (!boundary || (boundary.constructor !== Array && typeof boundary !== 'object')) {
      throw TAG + ': a boundary must be an array or non-null object';
    }
    return new Promise((resolve, reject) => {
      if (typeof boundary === 'object' && !boundary.id) {
        reject(TAG + ': an id is required')
      }

      RNBoundary.add(boundary)
        .then(id => resolve(id))
        .catch(e => reject(e))
    })
  },

  on: (event, callback) => {
    if (typeof callback !== 'function') {
      throw TAG + ': callback function must be provided';
    }
    if (!Object.values(Events).find(e => e === event)) {
      throw TAG + ': invalid event';
    }

    return boundaryEventEmitter.addListener(event, callback);
  },

  off: (event) => {
    if (!Object.values(Events).find(e => e === event)) {
      throw TAG + ': invalid event';
    }

    return boundaryEventEmitter.removeAllListeners(event);
  },

  removeAll: () => {
    return RNBoundary.removeAll();
  },

  remove: id => {
    if (!id || (id.constructor !== Array && typeof id !== 'string')) {
      throw TAG + ': id must be a string';
    }

    return RNBoundary.remove(id);
  }
}
paulrostorp commented 1 year ago

For iOS, According to this, I believe we need allowsBackgroundLocationUpdates to be set to true: https://developer.apple.com/documentation/corelocation/handling_location_updates_in_the_background?language=objc Screenshot 2023-02-11 at 15 34 10