vision-camera-code-scanner icon indicating copy to clipboard operation
vision-camera-code-scanner copied to clipboard

Android: Frame Processor threw an error: undefined is not a function

Open mancas opened this issue 3 years ago • 13 comments

Hi! First of all thanks for the lib! I'd like to start moving from the react-native-camera to react-native-vision-camera so the one of my app features is to read a barcode coded in EAN13 so this library fits my needs.

However I'm facing a strange issue, the frame processor is throwing an error all the time Frame Processor threw an error: undefined is not a function. All the configuration (especially the one related to react-reanimated) is done properly. The app is running fine and it compiles without errors.

babel.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        root: ['./'],
        extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
        alias: {
          res: './src/res',
        },
      },
    ],
    [
      'react-native-reanimated/plugin',
      {
        globals: ['__scanCodes'],
      },
    ],
  ],
}

Component

import React, { useEffect, useLayoutEffect, useMemo, useState } from 'react'
import { StatusBar } from 'react-native'
import styles from './GrantedPermissionsScreen.style'
import { Camera, useCameraDevices } from 'react-native-vision-camera'
import LoadingView from 'src/components/molecules/loadingView/LoadingView'
import Screen from 'src/components/atoms/screen/Screen'
import HeaderButton from 'src/components/molecules/headerButton/HeaderButton'
import { AvailableColors, colors } from 'res'
import IconFeather from 'react-native-vector-icons/Feather'
import Overlay from './components/overlay/Overlay'
import { CompositeNavigationProp } from '@react-navigation/core'
import { BarcodeFormat, useScanBarcodes } from 'vision-camera-code-scanner'
import { RegisterTubeRoutes, Routes } from 'src/navigators/routes'
import { RegisterTubeNavigationProp } from 'src/navigators/registerTube'
import { RootNavigationProp } from 'src/navigators'

// const ReanimatedCamera = Reanimated.createAnimatedComponent(Camera)

export interface GrantedPermissionsProps {
  navigation: CompositeNavigationProp<
    RegisterTubeNavigationProp<RegisterTubeRoutes.CameraGrantedPermissions>,
    RootNavigationProp<Routes.AddCustomer>
  >
}

const GrantedPermissionsScreen = ({ navigation }: GrantedPermissionsProps) => {
  const [hasPermission, setHasPermission] = useState(false)
  const devices = useCameraDevices()
  const device = useMemo(() => {
    return devices.back
  }, [devices])

  const [frameProcessor, barcodes] = useScanBarcodes([BarcodeFormat.QR_CODE])

  useLayoutEffect(() => {
    navigation.setOptions({
      headerTransparent: true,
      headerBackVisible: false,
      headerRight: () => {
        return (
          <HeaderButton
            variant={AvailableColors.white}
            onPress={navigation.goBack}>
            <IconFeather name="x" size={18} color={colors.white} />
          </HeaderButton>
        )
      },
    })
  }, [navigation])

  useEffect(() => {
    ;(async () => {
      const status = await Camera.requestCameraPermission()
      setHasPermission(status === 'authorized')
    })()
  }, [])

  if (!device || !hasPermission) {
    return <LoadingView />
  }

  return (
    <Screen style={styles.container}>
      <StatusBar barStyle="light-content" />

      <Camera
        style={styles.camera}
        isActive
        device={device}
        frameProcessor={frameProcessor}
        frameProcessorFps={5}
      />

      <Overlay />
    </Screen>
  )
}

export default React.memo(GrantedPermissionsScreen)

Hope someone can help me out to discover what's happening

Thanks!

mancas avatar Dec 16 '21 09:12 mancas

can you provide a repo with a react native setup containing this code that throw the same error?

rodgomescrn avatar Dec 16 '21 22:12 rodgomescrn

Sure! I've removed the unnecessary stuff. Also I've tried using SDK v31 but with the same results.

https://github.com/mancas/rn-test-app

mancas avatar Dec 17 '21 09:12 mancas

I'm facing the same issue !! any solution for it?

Kprashanth20 avatar Dec 21 '21 06:12 Kprashanth20

I get the same error after reload JS on Android (From debug menu or CodePush restart) Seem like the global function is not injected to JS runtime after reload. global.setFrameProcessor and global. unsetFrameProcessor is undefined.

This is where the module bind function with the javascript runtime global object: https://github.com/mrousavy/react-native-vision-camera/blob/b10ca27daabeb18ec3652ffc64fbbe0fecb298f5/android/src/main/cpp/FrameProcessorRuntimeManager.cpp#L36 After reload JS bundle, the global object has been reset, that's why we got undefined is not a function. I just think about the solution is check if the function is undefined then we need to call void vision::FrameProcessorRuntimeManager::registerNatives to bind it again.

ghost avatar Dec 26 '21 10:12 ghost

I have the same issue 'TypeError: undefined is not a function, js engine: hermes' the additional error are :

  • 'TypeError: Cannot read property 'scanQRCodes' of undefined'
  • 'Error: Requiring module "node_modules/vision-camera-qrcode-scanner/src/index.ts", which threw an exception: TypeError: undefined is not a function, js engine: hermes '

What I noticed is that id i comment out the line 'runOnJS(setQrCodes)(qrcode);' (default example) it works perfectly. if i uncomment the line when the camera is already on, it works as well. but if i let it uncommented and restart the app. i got those errors...

Bamorem avatar Jan 02 '22 15:01 Bamorem

Same issue here but only on iOS, works fine on Android.

I've got some additional info comming from xcode debug console, saying this :

Main Thread Checker: UI API called on a background thread: -[UIApplication statusBarOrientation] PID: 1305, TID: 878779, Thread name: (none), Queue name: mrousavy/VisionCamera.main, QoS: 33 Backtrace: 4 TitrePrepayes 0x0000000100ff5698 $s12VisionCamera0B4ViewC17updateOrientationyyFyycfU_yycfU_ + 1328 5 TitrePrepayes 0x0000000100ffa938 $sIeg_IeyB_TR + 20 6 libdispatch.dylib 0x000000010348b6f4 _dispatch_call_block_and_release + 24 7 libdispatch.dylib 0x000000010348cc78 _dispatch_client_callout + 16 8 libdispatch.dylib 0x0000000103494bf4 _dispatch_lane_serial_drain + 712 9 libdispatch.dylib 0x00000001034958b4 _dispatch_lane_invoke + 456 10 libdispatch.dylib 0x000000010349f77c _dispatch_workloop_worker_thread + 1148 11 libsystem_pthread.dylib 0x00000001a303d114 _pthread_wqthread + 304 12 libsystem_pthread.dylib 0x00000001a303fcd4 start_wqthread + 4 2022-01-10 11:24:07.790192+0100 TitrePrepayes[1305:878779] [reports] Main Thread Checker: UI API called on a background thread: -[UIApplication statusBarOrientation]

Followed by the error Frame Processor threw an error: Value is undefined, expected an Object

It seems to come from the react-native-vision-camera lib. When I comment out the frameProcessor props on Camera, I don't get any errors, but of course I can't scan any barcodes anymore.

Is anyone still on this issue ?

HartWoom avatar Jan 10 '22 10:01 HartWoom

Some update, I was using react-native-vision-camera v2.11.2. After downgrading to v2.11.1 (because the minor apparently was about device orientation) I do not have the above error anymore.

Although I still have Frame Processor threw an error: Value is undefined, expected an Object ^^

I went through https://mrousavy.com/react-native-vision-camera/docs/guides/troubleshooting, the only thing I haven't done yet was setting my swift version to 5.2. It unfortunately didn't solved anything.

I don't think I'm able to check what's happening inside the native code, I've never done swift before. I might have to search for another library unfortunately...

HartWoom avatar Jan 10 '22 11:01 HartWoom

I'm having the same issue, I made it work by not using the useScanBarcodes hook and declaring the frameProcessor function:

import React, { memo, useEffect, useState } from 'react';
import 'react-native-reanimated'
import { View } from 'react-native';
import { Camera, useCameraDevices, useFrameProcessor } from 'react-native-vision-camera';
import { BarcodeFormat, scanBarcodes, Barcode } from 'vision-camera-code-scanner';
import { runOnJS } from 'react-native-reanimated';

import styles from './styles';

function QRScanner() {

  const [hasPermission, setHasPermission] = useState(false);
  const devices = useCameraDevices();
  const device = devices.back; 
  const [barcodes, setBarcodes] = useState<Barcode[]>([])


  const frameProcessor = useFrameProcessor((frame) => {
    'worklet';
    const detectedBarcodes = scanBarcodes(frame, [BarcodeFormat.QR_CODE]);
    runOnJS(setBarcodes)(detectedBarcodes);
  }, []);
  
  useEffect(() => {
    (async () => {
      let status = await Camera.getCameraPermissionStatus();
      if (status === 'not-determined') {
        status = await Camera.requestCameraPermission();
      }
      setHasPermission(status === 'authorized');
    })();
  }, []);

  useEffect(() => {
    console.log(barcodes);
  }, [barcodes]);

  return (
    <View style={styles.container}>
      {device && hasPermission && <Camera
      style={styles.fill}
      device={device}
      isActive={true}
      frameProcessor={frameProcessor}
      frameProcessorFps={5}
    />}
    </View>
  );
}

export default memo(QRScanner);

DiegoQuiros94 avatar Jan 19 '22 20:01 DiegoQuiros94

I'm getting the same error, until I realised I need to disable the debugger as stated in troubleshoot

If your Frame Processor is not running, make sure you check the native Android Studio/Logcat logs to find out why. Also make sure you are not using a remote JS debugger such as Google Chrome, since those don't work with JSI.

anniewey avatar Mar 07 '22 14:03 anniewey

first of all it is recommended to clear the cache npm start -- --reset-cache

MihailShab avatar Apr 11 '22 10:04 MihailShab

Disabling the debug mode worked for me.

  1. Open the developer menu (pressing "d" on the metro console 👇​⌨️, or shaking 👋 your phone/device)
  2. Click on "Settings" ⚙️
  3. Uncheck "JS Dev Mode" 🐛 (first option)
  4. Reload your app 🔃 (pressing "r" on metro console 👇​⌨️)

Hope it helps 😉​

fthernan avatar Sep 21 '22 15:09 fthernan

Disabling the debug mode worked for me.

  1. Open the developer menu (pressing "d" on the metro console 👇​⌨️, or shaking 👋 your phone/device)
  2. Click on "Settings" ⚙️
  3. Uncheck "JS Dev Mode" 🐛 (first option)
  4. Reload your app 🔃 (pressing "r" on metro console 👇​⌨️)

Hope it helps 😉​

I can confirm that disabling the Debugger in the developer menu in the iPhone works.

JoseMariaZoe avatar Oct 26 '22 11:10 JoseMariaZoe

Hi -- I'm trying to disable the debugger but I don't have that option in the menu when I shake the device, see image.

I think because it's hermes.

Also - pressing D in metro doesn't open the menu... is there any other way to disable? IMG_5837

Peege151 avatar Nov 17 '22 07:11 Peege151