expo: BarCodeScanner intermittently crashes app on render

Summary

When rendering the BarCodeScanner component from expo-barcode-scanner, the entire app sometimes locks up. The parent component is visible, but the camera viewport itself never renders. The app must be quit and restarted.

  • Occurs intermittently, unclear what the trigger is. A device can use the scanner successfully only to have it crash later.
  • Only observed in deployed app binaries, not in Expo Go
  • Only observed in iOS
  • A wrapping ErrorBoundary component does not catch errors generated by this event

What platform(s) does this occur on?

iOS

Environment

  expo-env-info 1.0.5 environment info:
    System:
      OS: macOS 12.4
      Shell: 5.8.1 - /bin/zsh
    Binaries:
      Node: 16.15.1 - /usr/local/bin/node
      npm: 8.11.0 - /usr/local/bin/npm
      Watchman: 2022.08.15.00 - /opt/homebrew/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5
    IDEs:
      Android Studio: 2021.2 AI-212.5712.43.2112.8609683
      Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild
    npmPackages:
      expo: ^45.0.0 => 45.0.8 
      react: 17.0.2 => 17.0.2 
      react-dom: 17.0.2 => 17.0.2 
      react-native: 0.68.2 => 0.68.2 
      react-native-web: 0.17.7 => 0.17.7 
    npmGlobalPackages:
      eas-cli: 0.59.0
      expo-cli: 6.0.2
    Expo Workflow: managed

expo-barcode-scanner: 11.3.0

Minimal reproducible example

Credit to @ChrisOliverFD for this great Snack demo:

https://snack.expo.dev/@unktomi/barcode-scanner

Just open and close the modal repeatedly to see the crash. This is the same behavior that was seen in my app, and my app shared the structure of a BarCodeScanner in a react-router modal . Worth noting though that the crash did not just occur when artificially reproduced by rapidly opening and closing the modal. Users regularly triggered the crash though normal usage, including times when the modal had not been open for multiple minutes.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 3
  • Comments: 19 (6 by maintainers)

Most upvoted comments

@brentvatne I’ve run into the same issue and was able to solve it by switching to the expo-camera module rather than using expo-barcode-scanner. I believe the expo-barcode-scanner module was having issues particularly when used in tandem with react-navigation. I believe the bug occurs when a BarCodeScanner component is rendered before the previously rendered BarCodeScanner component is completely unmounted. For some reason, the Camera component from expo-camera does not seem to have this issue. The expo-camera module even has support for the camera flash among many other useful functions! I hope it solves your problem 😃

Example usage:

useEffect(() => {
  async function getBarCodeScannerPermission() {
      try {
        const { status } = await Camera.requestCameraPermissionsAsync();
        setHasPermission(status === PermissionStatus.GRANTED);
      } catch(error) {
        console.log(error);
      }
  };
  getBarCodeScannerPermission();
}, []);
function handleBarCodeScanned({ type, data }) {
  setData(data);
  setScanned(true);
};
return (
{ hasPermission && scanned &&
  <Camera
      style={StyleSheet.absoluteFillObject}
      key={scanned ? 1 : 2}
      barCodeScannerSettings={{
          barcodeTypes: [ // You still need the expo-barcode-scanner module for the BarCodeScanner constants
              BarCodeScanner.Constants.BarCodeType.{...} // Specify what types you'd like to scan here
          ]
      }}
      onBarCodeScanned={handleBarCodeScanned}
      flashMode={flashOn ? FlashMode.torch : FlashMode.off}
  />
}
);

Note: Just make sure to add key={scanned ? 1 : 2} to your Camera component if you’re having trouble scanning a barcode the 2nd time!

A couple of addendums from my time trying to debug this issue that might prove helpful:

  • It turns out you can trigger the crash from Expo Go, so if you are trying to debug you don’t have to go through a whole build
  • I was using react-router like many others with this issue. The QR scanner was in a modal, and in testing I often triggered the crash by rapidly opening and closing the modal. That said, I am doubtful that the issue is two scanners being rendered at once, unless old react-router modals sometimes stick around for a very long time. In attempting to work around this issue I experimented with delays in rendering the scanner. Even when I artificially waited multiple seconds before rendering the scanner, I was still able to trigger crashes. The app also frequently crashed during play tests, and players do not usually rapidly open and close the modal. And my memory is fuzzy at this point, but I remember the app freezing when it was the first time I opened the scanner in quite awhile, multiple minutes.
  • #19199 appears to be the same issue and includes a great minimum reproducible demo of the crash: https://snack.expo.dev/@unktomi/barcode-scanner

Figured I’d pull out the old Expo version of my game and give this expo-camera workaround a try… and it works!

I’ve only done some quick tests, but I basically just swapped out BarCodeScanner for Camera and everything seems to work fine. I was unable to trigger a freeze after some ~200 attempts.

So it is too late for me, but for anyone doing QR scans in Expo in the future, just treat expo-barcode-scanner as if it is deprecated. I don’t know of any features it has that expo-camera does not have, and there are has some showstopper bugs that have not been addressed in nearly half a year.

@brentvatne I’ve run into the same issue and was able to solve it by switching to the expo-camera module rather than using expo-barcode-scanner. I believe the expo-barcode-scanner module was having issues particularly when used in tandem with react-navigation. I believe the bug occurs when a BarCodeScanner component is rendered before the previously rendered BarCodeScanner component is completely unmounted. For some reason, the Camera component from expo-camera does not seem to have this issue. The expo-camera module even has support for the camera flash among many other useful functions! I hope it solves your problem 😃

This seems to have been the fix for us. Literally switching from:

<BarCodeScanner
    onBarCodeScanned={onScan}
/>

to

<Camera
    onBarCodeScanned={onScan}
/>

hi @delventhalz, this was triaged as part of an automatic issue validation process in order to attempt to get control over issues, as there was too much noise for us to work through. we ask that a minimal reproducible example is a clonable github repo or link to a snack that we can run. our issue validation looks for links to git repos or snacks. this was not always so well articulated, and apologies if this is confusing now. six months indeed is a long time, and sadly this was buried. as we filter our issues down to a smaller list of actionable issues we can work through those. if you’d like to dig in to the issue and open a pr, that would also be welcome.

Hey @brentvatne, a quote from the comment directly above your bot:

#19199 appears to be the same issue and includes a great minimum reproducible demo of the crash: https://snack.expo.dev/@unktomi/barcode-scanner

Not to mention the MRE from my original Issue post nearly six months ago.

This is a consistent, reproducible, breaking issue with expo-barcode-scanner that has been clearly documented by multiple users. If it is your position that the issue will not be fixed, then mark expo-barcode-scanner as deprecated and point your users to a working alternative like expo-camera.

Hi there! It looks like your issue requires a minimal reproducible example, but it is invalid or absent. Please prepare such an example and share it in a new issue.

The best way to get attention to your issue is to provide a clean and easy way for a developer to reproduce the issue on their own machine. Please do not provide your entire project, or a project with more code than is necessary to reproduce the issue.

A side benefit of going through the process of narrowing down the minimal amount of code needed to reproduce the issue is that you may get lucky and discover that the bug is due to a mistake in your application code that you can quickly fix on your own.

Resources

Common concerns

“I’ve only been able to reproduce it in private, proprietary code”

You may not have spent enough time narrowing down the root cause of the issue. Try out the techniques discussed in this manual debugging guide to learn how to isolate the problem from the rest of your codebase.

“I didn’t have time to create one”

That’s understandable, it can take some time to prepare. We ask that you hold off on filing an issue until you are able to fully complete the required fields in the issue template.

“You can reproduce it by yourself by creating a project and following these steps”

This is useful knowledge, but it’s still valuable to have the resulting project that is produced from running the steps, where you have verified you can reproduce the issue.