π Error when create BleManager instance
Santa0727 opened this issue Β· comments
Prerequisites
- I checked the documentation and FAQ without finding a solution
- I checked to make sure that this issue has not already been filed
Expected Behavior
Hello,
I want to create a new BleManager instance using the following code.
const bleManager = useMemo(() => new BleManager(), []);
function useBLE(): BluetoothLowEnergyApi {
const bleManager = useMemo(() => new BleManager(), []);
.....
}
I want the above code to be working on expo 50.
Current Behavior
const bleManager = useMemo(() => new BleManager(), []);
Currently, the above code makes the following error:
ERROR TypeError: Cannot read property 'createClient' of null
This error is located at:
in App (at withDevTools.js:18)
in withDevTools(App) (at renderApplication.js:57)
in RCTView (at View.js:116)
in View (at AppContainer.js:127)
in RCTView (at View.js:116)
in View (at AppContainer.js:155)
in AppContainer (at renderApplication.js:50)
in main(RootComponent) (at renderApplication.js:67), js engine: hermes
ERROR TypeError: Cannot read property 'createClient' of null
This is the dependencies in my package.json file:
"dependencies": {
"@shopify/react-native-skia": "0.1.221",
"expo": "~50.0.14",
"expo-device": "~5.9.4",
"expo-splash-screen": "~0.26.4",
"expo-status-bar": "~1.11.1",
"react": "18.2.0",
"react-native": "0.73.6",
"react-native-base64": "^0.2.1",
"react-native-ble-plx": "^3.1.2"
},
Library version
^3.1.2
Device
Android 10, Platform API Level 29
Environment info
I am using expo
Steps to reproduce
- Create fresh typescript expo project
- Create useBLE.ts file and then copy the following code
import { useMemo, useState } from "react";
import { PermissionsAndroid, Platform } from "react-native";
import { BleManager, Device } from "react-native-ble-plx";
import * as ExpoDevice from "expo-device";
interface BluetoothLowEnergyApi {
requestPermissions(): Promise<boolean>;
scanForPeripherals(): void;
allDevices: Device[];
connectToDevice: (deviceId: Device) => Promise<void>;
connectedDevice: Device | null;
}
function useBLE(): BluetoothLowEnergyApi {
const bleManager = useMemo(() => new BleManager(), []);
const [allDevices, setAllDevices] = useState<Device[]>([]);
const [connectedDevice, setConnectedDevice] = useState<Device | null>(null);
const requestAndroid31Permissions = async () => {
const bluetoothScanPermissions = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, {
title: "Scan Permission",
message: "App requires Bluetooth Scanning",
buttonPositive: "OK",
});
const bluetoothConnectPermissions = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
{
title: "Connecting Permission",
message: "App requires Bluetooth Connecting",
buttonPositive: "OK",
}
);
const bluetoothFineLocationPermissions = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: "Fine Location",
message: "App requires Fine Location",
buttonPositive: "OK",
}
);
return (
bluetoothScanPermissions === "granted" &&
bluetoothConnectPermissions === "granted" &&
bluetoothFineLocationPermissions === "granted"
);
};
const requestPermissions = async () => {
if (Platform.OS === "android") {
if ((ExpoDevice.platformApiLevel ?? -1) < 31) {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, {
title: "Location Permission",
message: "Bluetooth requires Location",
buttonPositive: "OK",
});
return granted === PermissionsAndroid.RESULTS.GRANTED;
} else {
const isAndroid31PermissionsGranted = await requestAndroid31Permissions();
return isAndroid31PermissionsGranted;
}
} else {
return true;
}
};
const isDuplicatedDevice = (devices: Device[], nextDevice: Device) =>
devices.some((device) => device.id === nextDevice.id);
const scanForPeripherals = () => {
};
const connectToDevice = async (device: Device) => {
};
return { scanForPeripherals, requestPermissions, allDevices, connectToDevice, connectedDevice };
}
export default useBLE;
- Copy the following code into App.tsx file
import { SafeAreaView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
import useBLE from "./useBLE";
import { useState } from "react";
import DeviceModal from "./DeviceConnectionModal";
const App = () => {
const { requestPermissions } = useBLE();
const [visible, setVisible] = useState(false);
const connectedDevice = false;
const scanForDevices = async () => {
};
const openModal = () => {
scanForDevices();
setVisible(true);
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.heartRateTitleWrapper}>
{connectedDevice ? (
<>
<Text style={styles.heartRateTitleText}>Your Heart Rate Is:</Text>
{/* <Text style={styles.heartRateText}>{heartRate} bpm</Text> */}
</>
) : (
<Text style={styles.heartRateTitleText}>Please Connect to a Heart Rate Monitor</Text>
)}
</View>
<TouchableOpacity
// onPress={connectedDevice ? disconnectFromDevice : openModal}
onPress={openModal}
style={styles.ctaButton}
>
<Text style={styles.ctaButtonText}>{connectedDevice ? "Disconnect" : "Connect"}</Text>
</TouchableOpacity>
{/* <DeviceModal
closeModal={() => setVisible(false)}
visible={visible}
connectToPeripheral={connectToDevice}
devices={allDevices}
/> */}
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f2f2f2",
},
heartRateTitleWrapper: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
heartRateTitleText: {
fontSize: 30,
fontWeight: "bold",
textAlign: "center",
marginHorizontal: 20,
color: "black",
},
heartRateText: {
fontSize: 25,
marginTop: 15,
},
ctaButton: {
backgroundColor: "#FF6060",
justifyContent: "center",
alignItems: "center",
height: 50,
marginHorizontal: 20,
marginBottom: 5,
borderRadius: 8,
},
ctaButtonText: {
fontSize: 18,
fontWeight: "bold",
color: "white",
},
});
export default App;
Formatted code sample or link to a repository
import { BleManager } from 'react-native-ble-plx'
export const manager = new BleManager()
Relevant log output
ERROR TypeError: Cannot read property 'createClient' of null
This error is located at:
in App (created by withDevTools(App))
in withDevTools(App) (at renderApplication.js:57)
in RCTView (at View.js:116)
in View (at AppContainer.js:127)
in RCTView (at View.js:116)
in View (at AppContainer.js:155)
in AppContainer (at renderApplication.js:50)
in main(RootComponent) (at renderApplication.js:67), js engine: hermes
ERROR TypeError: Cannot read property 'createClient' of null
Additional information
No response
Hi @Santa0727
Thank you for raising the issue; we'll verify it and get back to you soon.
@Santa0727
It works for me :D
It looks like you used the standard "expo start" app launch, but this package uses native code that needs to be prebuilt.
Check
- https://github.com/dotintent/react-native-ble-plx?tab=readme-ov-file#expo-sdk-43
- https://docs.expo.dev/workflow/customizing/
My code for this issue check: - https://github.com/dominik-czupryna-withintent/ble-plx-issues-1188
Btw.
You should have only one BLE instance, in your case a new one will be created every time you use the useBLE hook.
Hi @dominik-czupryna-withintent ,
Thank you for your response!
You are right, I used standard expo-managed flow without ejecting.
Is it impossible to use this library inside the expo without eject?
@Santa0727 Use Expo Development Build. eject Expo is not a thing any more.
Hi @Santa0727
Is your issue is still relevant, do you need any help?
Hi @Santa0727
Do you still need help with the issue?
Closing due to inactivity