MacKentoch / react-native-beacons-manager

React-Native library for detecting beacons (iOS and Android)
MIT License
579 stars 318 forks source link

App throws an error after run initial with a minimal example #256

Open iSaBo96 opened 1 year ago

iSaBo96 commented 1 year ago

Version

1.1.0

Platform

iOS

OS version

iOS 13

General versions

  1. react-native: 068.0
  2. react: 17.0.2
  3. beacon library: 1.1.0
  4. pod. 1.11.3
  5. npm: 9.2.0
  6. node: 18.1.0

Steps to reproduce

  1. react-native init myTestApp --version=0.68.0
  2. Add library version 1.1.0 ("react-native-beacons-manager": "git://github.com/MacKentoch/react-native-beacons-manager.git#53c1bda")
  3. cd ios && pod install
  4. add minimal example
import React from 'react';

import {Text, View} from 'react-native';

import {Beacons} from 'react-native-beacons-manager';

const App = ({route, navigation}) => {
    Beacons.requestAlwaysAuthorization();
    Beacons.allowsBackgroundLocationUpdates(true);

    return (
        <View>
          <Text style={{color: 'white', top: 150}}>test</Text>
        </View>
    );
};

export default App;

Expected behavior

The app should be started successfully

Actual behavior

I get the following errors:

Error: Requiring module "node_modules/react-native-beacons-manager/index.js", which threw an exception: Invariant Violation: `new NativeEventEmitter()` requires a non-null argument. 

TypeError: undefined is not an object (evaluating '_$$_REQUIRE(_dependencyMap[2], "react-native-beacons-manager").Beacons')

I have used the library several times in my projects. But now I get the mentioned error and don't know why. I have even created a minimal example. This is described above. But still I have the error. Does anyone know why?

sashko9807 commented 1 year ago

Beacons is default export. Try import Beacons from 'react-native-beacons-manager'; instead of import {Beacons} from 'react-native-beacons-manager';

gigflex commented 1 year ago

Hi @iSaBo96 ,

Are you able to make it work?

iSaBo96 commented 1 year ago

@gigflex yes, what is your problem with this?

sangheraajit commented 1 year ago

Hi @iSaBo96

we are able to run the code somehow but getting the following error

[CoreBluetooth] XPC connection invalid 2023-03-13 21:48:22.061407+0530 beaconApp[4021:2131472] [javascript] iosPLatform 2023-03-13 21:48:22.062827+0530 beaconApp[4021:2130220] createBeaconRegion with: identifier - uuid 2023-03-13 21:48:22.062945+0530 beaconApp[4021:2130220] [Client] {"msg":"Region is nil"} 2023-03-13 21:48:22.063305+0530 beaconApp[4021:2129927] Failed ranging region: Error Domain=kCLErrorDomain Code=17 "(null)"

beaconsDidRange never fires

iSaBo96 commented 1 year ago

Have you linked the library?

You must link the library in XCode under "Libraries". You have to link the binary "RNiBeacon.a" in you project phases

iSaBo96 commented 1 year ago

which version do you use?

sangheraajit commented 1 year ago

@iSaBo96 We are using git+https://github.com/MacKentoch/react-native-beacons-manager.git

and ios 13 We are unable to find RNiBeacon.a

image
sangheraajit commented 1 year ago

Hi @iSaBo96 ,

We are able to see Beacons ranging started succesfully and Beacons monitoring started succesfully

log but beaconsDidRange event never fires

image
iSaBo96 commented 1 year ago

You have to add RNiBeacon.a

I also use "react-native-beacons-manager": "git+https://github.com/MacKentoch/react-native-beacons-manager.git", in my package.json file.

image

Please follow the path in the screenshot to add the RNiBeacon.a. If you do not found it, do a "pod install" in your ios folder

iSaBo96 commented 1 year ago

And you have to link the library manually

image

And you have to the the following path in the linked library. Go there to "build settings" and add the following:

image

In your App you have to add the following under "Build settings" > "Header Search Paths"

image

sangheraajit commented 1 year ago

Hi @iSaBo96

Do you have a working copy if you can share that will be a great help. Thanks

iSaBo96 commented 1 year ago

Please tell me which react-native version you are using. I Use 0.70.6. I have a working copy, but i cannot share this, because it is a production code.

From which country you are? Maybe i can offer you a call tomorrow? I come from germany and the current time is 18:45

sangheraajit commented 1 year ago

Hi

We tried with 0.71.0 we tried with 0.64.4 I am from India Following is my skype id swesoftm42 my email is ajit@gigflex.com

iSaBo96 commented 1 year ago

Do you habe discord? I dont have skype

sangheraajit commented 1 year ago

Hi @iSaBo96

This is my discord id sangheraajit#3485

iSaBo96 commented 1 year ago

I sended you a request

sangheraajit commented 1 year ago

HI @iSaBo96 ,

I m able to get this added "RNiBeacon.a" to the project but getting the following error

image
iSaBo96 commented 1 year ago

You have to link the library manually

image

Drag and drop from "node_modules/react-native-beacons-manager/ios/RNiBeacon.xcodeproj

sangheraajit commented 1 year ago

Hi @iSaBo96

Did the same thing after doing some changes according to your instruction we got the following error

image
iSaBo96 commented 1 year ago

Lets wait till we speak plase

Jaszczab20 commented 1 year ago

@sangheraajit were you able to solve the issue with duplicate symbols?

Jaszczab20 commented 12 months ago

Hi @iSaBo96

Did the same thing after doing some changes according to your instruction we got the following error

image

I have experienced the same issue and I was able to solve it by following this https://github.com/facebook/react-native/issues/27840#issuecomment-623052433

sangheraajit commented 12 months ago

HI @Jaszczab20 , Thanks for your response. We have fixed the issue in some other way

AlbertoLopSie commented 11 months ago

@sangheraajit, @iSaBo96

Hi guys,

I'm trying to make this library work with RN 0.72.5 on iOS with no luck.

Are you using THIS repo or any of the many forks out here? What version of RN are you successfully using? What iOS version are you successfully using?

Thanks!! Alberto

iSaBo96 commented 11 months ago

I use the version i wrote above :)

JayvishEsofts commented 2 months ago

@sangheraajit, @iSaBo96

Hi guys,

I'm trying to make this library work with RN 0.72.5 on iOS with no luck.

Are you using THIS repo or any of the many forks out here? What version of RN are you successfully using? What iOS version are you successfully using?

Thanks!! Alberto

Hi Alberto,

Now with newer react native version supporting auto-Linking and you can follow these steps

TESTED on React Native 0.74.2

Step 1. Install the package as npm install react-native-beacons-manager@git+https://github.com/MacKentoch/react-native-beacons-manager.git

Step 2. Pod Install npx pod install

Step 3. Finally use it in you JS (No Manual Linking Required)

requestBeaconPermissions.js

import {Alert, Linking, PermissionsAndroid, Platform} from 'react-native';
import {PERMISSIONS, requestMultiple, RESULTS} from 'react-native-permissions';

export const requestPermissions = async () => {
  if (Platform.OS === 'android' && Platform.Version >= 23) {
    try {
      console.log('Requesting permissions...');

      const permissions = [
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
      ];

      if (Platform.Version >= 31) {
        // Android 12 and above
        permissions.push(
          PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
          PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
          PermissionsAndroid.PERMISSIONS.BLUETOOTH_ADVERTISE,
        );
      } else {
        permissions.push(
          PermissionsAndroid.PERMISSIONS.BLUETOOTH,
          PermissionsAndroid.PERMISSIONS.BLUETOOTH_ADMIN,
        );
      }

      const granted = await PermissionsAndroid.requestMultiple(permissions);

      console.log('Permissions granted result:', granted);

      const neverAskAgain = Object.values(granted).includes(
        PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN,
      );
      if (neverAskAgain) {
        Alert.alert(
          'Permissions required',
          'Some permissions are permanently denied. Please enable them in the app settings.',
          [
            {text: 'Cancel', style: 'cancel'},
            {text: 'Open Settings', onPress: () => Linking.openSettings()},
          ],
        );
        return false;
      }

      const allGranted = permissions.every(
        permission =>
          granted[permission] === PermissionsAndroid.RESULTS.GRANTED,
      );

      return allGranted;
    } catch (err) {
      console.warn('Permissions request error:', err);
      return false;
    }
    } else {
      if (Platform.OS === 'ios') {
        // request permission on IOS
        let allGranted = false;
        await requestMultiple([
          PERMISSIONS.IOS.BLUETOOTH,
          PERMISSIONS.IOS.LOCATION_ALWAYS,
        ]).then(statuses => {
          if (
            statuses[PERMISSIONS.IOS.BLUETOOTH] === RESULTS.GRANTED &&
            statuses[PERMISSIONS.IOS.LOCATION_ALWAYS] === RESULTS.GRANTED
          ) {
            allGranted = true;
          } else {
            allGranted = false;
          }
        });
        return allGranted;
      } else {
        return false;
      }
    }
  };

Now in App.js

import React, {useState, useEffect} from 'react';
  import {
    View,
    Text,
    Platform,
    FlatList,
    StyleSheet,
    AppState,
  } from 'react-native';
  import Beacons from 'react-native-beacons-manager';
  import {requestPermissions} from './requestBeaconPermission';

  function App() {
    const [beaconData, setBeaconData] = useState(null);
    const [appState, setAppState] = useState(AppState.currentState);

    useEffect(() => {
      const regions = [
        {
          identifier: 'iBeacon',
          uuid: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', // REQUIRED FOR IOS IN THIS FORMAT - B9407F30-F5F8-466E-AFF9-25556B57FE6D - Replace with your beacon UUID
        },
      ];
    const initializeBeacons = async () => {
      if (Platform.OS === 'ios') {
        const permissionsGranted = await requestPermissions();
        console.log('AllGranted IOS', permissionsGranted);
        if (permissionsGranted) {
          try {
            regions.forEach(region => {
              Beacons.startRangingBeaconsInRegion({
                identifier: region.identifier,
                uuid: region.uuid,
              })
                .then(() => {
                  console.log('Beacons ranging started successfully');
                })
                .catch(error =>
                  console.log(`Beacons ranging not started, error: ${error}`),
                );

              Beacons.startUpdatingLocation();
            });
          } catch (error) {
            console.log(`Beacons ranging not started, error: ${error}`);
          }
        }
      } else {
        const permissionsGranted = await requestPermissions();
        if (permissionsGranted) {
          Beacons.detectIBeacons();
          try {
            regions.forEach(region => {
              Beacons.startRangingBeaconsInRegion(region);
              console.log('Beacons ranging started successfully!');
            });
          } catch (err) {
            console.log(`Beacons ranging not started, error: ${err}`);
          }
        } else {
          console.log('Permissions not granted');
        }
      }

      global.beaconListener = await Beacons.BeaconsEventEmitter.addListener(
        'beaconsDidRange',
        handleBeaconsDidRange,
      );
    };

      initializeBeacons();

      const handleAppStateChange = nextAppState => {
        if (appState.match(/inactive|background/) && nextAppState === 'active') {
          requestPermissions();
        }
        setAppState(nextAppState);
      };

      global.appStateListener = AppState.addEventListener(
        'change',
        handleAppStateChange,
      );

      return () => {
        global?.beaconListener?.remove();
        global?.appStateListener?.remove();
      };
    }, [appState]);

    const handleBeaconsDidRange = data => {
      console.log('beaconsDidRange', data);
      if (data.beacons.length > 0) {
        setBeaconData(data.beacons);
      }
    };
    };

    const renderRow = ({item}) => (
      <View style={styles.row}>
        <Text style={styles.smallText}>UUID: {item.uuid ? item.uuid : 'NA'}</Text>
        <Text style={styles.smallText}>
          Major: {item.major ? item.major : 'NA'}
        </Text>
        <Text style={styles.smallText}>
          Minor: {item.minor ? item.minor : 'NA'}
        </Text>
        <Text>RSSI: {item.rssi ? item.rssi : 'NA'}</Text>
        <Text>Proximity: {item.proximity ? item.proximity : 'NA'}</Text>
        <Text>Distance: {item.accuracy ? item.accuracy.toFixed(2) : 'NA'}m</Text>
      </View>
    );

    return (
      <View style={styles.container}>
        {beaconData && beaconData.length > 0 ? (
          <FlatList
            data={beaconData}
            renderItem={renderRow}
            keyExtractor={(item, index) => index.toString()}
          />
        ) : (
          <Text>No beacons detected</Text>
        )}
      </View>
    );
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      paddingTop: 60,
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: '#F5FCFF',
    },
    row: {
      padding: 8,
      paddingBottom: 16,
    },
    smallText: {
      fontSize: 11,
    },
  });

  export default App;

Thats it!!!!

Hope this helps