react-native-ble-plx: ❌ ERROR: Invariant Violation: `new NativeEventEmitter()` requires a non-null argument. - Project Setup

Prerequisites

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed
  • I checked all example applications mentioned in README file and they don’t work for me.
  • I followed every installation step mentioned in README file.

Setup problem

I am trying to setup react-native-ble-plx to my expo app but I am getting this error:

ERROR  Invariant Violation: `new NativeEventEmitter()` requires a non-null argument.

Steps to Reproduce

import React, { useState } from "react";
import {
  View,
  Text,
  TouchableOpacity,
  StyleSheet,
  Button,
  ImageBackground,
  Image,
} from "react-native";
import { COLORS, SIZES, assets, styles1, styles2 } from "../constants";
import { Avatar } from "@rneui/themed";
import { BleManager } from "react-native-ble-plx";
import DeviceCard from "../components/DeviceCard";


const Home = ({ navigation }) => {
  const manager = React.useRef();
  manager.current = new BleManager({
    restoreStateIdentifier: 'com.baucapstone.smartdoorlock',
    restoreStateFunction: () => {},
    allowDuplicate: false,
  });

  var devices = [];

  const [isLoading, setIsLoading] = useState(false);

  const scanDevices = () => {
    setIsLoading(true);

    manager.startDeviceScan(null, null, (error, scannedDevice) => {
      if (error) {
        console.warn(error);
      }
      if (scannedDevice && !devices.find((dev) => dev.id === scannedDevice.id)) {
        console.log(scannedDevice)
        devices = [
          ...devices,
          {id: scannedDevice.id, name: scannedDevice.name},
        ];
      }
    });

    setTimeout(() => {
      manager.stopDeviceScan();
      setIsLoading(false);
    }, 5000);
  };

  return (
    <View
      style={{
        flex: 1,
      }}
    >
      <Button color="#3b5998" title="Scan bluetooth devices" onPress={scanDevices} />
      {devices.map((device) => <DeviceCard device={device} />)}
      <ImageBackground
        source={require("../assets/images/background.png")}
        resizeMode="cover"
        style={{
          flex: 1,
          justifyContent: "center",
        }}
      >
        <View
          style={{
            flex: 1,
            justifyContent: "space-around",
            alignItems: "center",
          }}
        >
          <View
            style={{
              width: "100%",
              alignItems: "flex-start",
              top: -45,
              left: 10,
            }}
          >
            <Text
              style={{
                fontSize: SIZES.extraLarge,
                fontWeight: "bold",
              }}
            >
              Home
            </Text>
          </View>
          <View>
            <TouchableOpacity
              style={{
                borderWidth: 2,
                borderColor: "#0782F9",
                width: 200,
                padding: 15,
                paddingRight: 30,
                borderRadius: 10,
                alignItems: "center",
                flexDirection: "row",
                justifyContent: "space-around",
                alignItems: "center",
              }}
            >
              <Image source={require("../assets/icons/unlock.png")} />
              <Text
                style={{
                  fontSize: 18,
                  fontWeight: "bold",
                }}
              >
                Lock
              </Text>
            </TouchableOpacity>
          </View>
          <View
            style={{ flexDirection: "row", alignItems: "center", top: -60 }}
          >
            <Avatar
              size="medium"
              rounded
              source={{ uri: "https://i.pravatar.cc/400" }}
            />
            <View
              style={{
                padding: 10,
              }}
            >
              <Text style={{ fontWeight: "bold" }}>
                last access 7.46AM by bilgesu
              </Text>
              <Text style={{ fontWeight: "bold" }}>door was unlocked</Text>
            </View>
          </View>
        </View>
      </ImageBackground>
    </View>
  );
};

export default Home;
  • Library version: latest version
  • Platform: iOS.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15

Most upvoted comments

I’m in a fresh Expo project and getting this slightly longer error:

`new NativeEventEmitter()` was called with a non-null argument without the required `addListener` method.
at node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:62:8 in constructor
at node_modules/react-native-ble-plx/src/BleManager.js:66:25 in constructor

I changed BleManager.js like this, but this is not a proper solution:

  /**
   * Creates an instance of {@link BleManager}.
   */
  constructor(options: BleManagerOptions = {}) {
+    if (!BleModule.addListener)BleModule.addListener=console.warn
+    if (!BleModule.removeListeners)BleModule.removeListeners=console.warn

Version 3.1.1 but still having this issue@@

The new major release updates the core packages that support the latest versions of the operating system and fixes some old bugs. Please confirm if the issue still persists and create a new issue if it still does.

I still get this issue on the latest @config-plugins/react-native-ble-plx, expo and react-native-ble-plx.

It seems the issue is as follows. NativeEventEmitter takes the nativeModule argument passed to the constructor so it can notify a native module of how many listeners there are (something to do with conserving bridge traffic, I suppose - if there are zero listeners on an emitter, the native layer can choose not to emit an event?). This is required on iOS, not entirely sure why.

  • 1 (on iOS) nativeModule must be present and must include the addListener/removeListeners methods.
  • 2 (on Android) nativeModule argument can be missing (2a), be passed and include the addListener/removeListeners methods (2b), or be passed without those methods (2c).

It seems the (2c) case issues this warning. It appears to be resolved by passing the nativeModule argument as undefined to NativeEventEmitter if Platform.OS === "android".

Alternatively, we can add empty dummy implementations of the addListener/removeListeners methods when on Android. This can be done by monkey patching (in javascript) the BleModule exported from react-native-ble-plx/src/BleModule before creating a BleManager. This is a temporary hack and would better be done in the java layer.

I could PR either of these options, but not sure which is best and the repo seems to be unmaintained… I was initially tripped up by #730 thinking this warning was breaking my app on Android, but it was just the permissions issue.

Expo users: Upgraded @config-plugins/react-native-ble-plx to version 5.0.0, and the warning went away.

I’m also encountering the same issue using Expo.

Project seems dead, there hasn’t been any commits for 10 months. 😮

Are you using expo?