DEV Community

Cover image for React Native QR Code Reader / QR Code Scanner July 2024
RamR
RamR

Posted on • Edited on

32

React Native QR Code Reader / QR Code Scanner July 2024

I tired a different way to implement qr code reading functionality and I want to share it with you. Since the general approach of using react-native-qrcode-scanner, this package not updated recently or not maintained. So I went to try out this react-native-vision-camera package.

Package

yarn add react-native-vector-icons
yarn add react-native-vision-camera
Enter fullscreen mode Exit fullscreen mode

Configuration

iOS


cd ios && pod install

Enter fullscreen mode Exit fullscreen mode

info.plist

<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Camera.</string>
Enter fullscreen mode Exit fullscreen mode

Android

AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" />
Enter fullscreen mode Exit fullscreen mode

gradle.properties

VisionCamera_enableCodeScanner=true
Enter fullscreen mode Exit fullscreen mode

HomePage

import React, { useState } from "react";
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  Dimensions,
} from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
import QRScanner from "./qrScanner";
const dWidth = Dimensions.get("window").width;

const clr1 = "mediumseagreen";

const ScanQRPage = () => {
  const [showQR, setShowQR] = useState(false);
  const [qrCode, setQrCode] = useState("");

  const openQRscanner = () => {
    setShowQR(true);
  };

  const onQrRead = (qrtext) => {
    setQrCode(qrtext);
    setShowQR(false);
  };

  return (
    <View style={styles.page}>
      {qrCode ? (
        <Text style={{ fontSize: 16, color: "black" }}>
          {"QR Value \n" + qrCode}
        </Text>
      ) : null}
      <Ionicons
        name={"scan-circle-outline"}
        size={qrCode ? dWidth * 0.4 : dWidth * 0.75}
        color={clr1}
      />
      <TouchableOpacity onPress={() => openQRscanner()} style={styles.btn}>
        <Text style={{ color: clr1 }}>Scan QR</Text>
      </TouchableOpacity>
      {showQR ? <QRScanner onRead={onQrRead} /> : null}
    </View>
  );
};

export default ScanQRPage;

const styles = StyleSheet.create({
  page: {
    flex: 1,
    backgroundColor: "white",
    alignItems: "center",
    justifyContent: "space-evenly",
  },
  btn: {
    backgroundColor: "transparent",
    alignItems: "center",
    borderRadius: 10,
    paddingVertical: "3%",
    width: "50%",
    borderWidth: 2,
    borderColor: clr1,
  },
  btnText: {
    color: clr1,
  },
});

Enter fullscreen mode Exit fullscreen mode

Image description

QR Scanner / Reader Component

import React, { useState, useEffect } from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import {
  Camera,
  useCameraDevice,
  useCodeScanner,
} from "react-native-vision-camera";
import Ionicons from "react-native-vector-icons/Ionicons";

const QRScanner = (props) => {
  const [hasPermission, setHasPermission] = useState(false);
  const [refresh, setRefresh] = useState(false);
  const device = useCameraDevice("back");
  const codeScanner = useCodeScanner({
    codeTypes: ["qr"],
    onCodeScanned: (codes) => {
      console.log(`onCodeScanned `, codes);
      console.log(`onCodeScanned value`, codes[0].value);
      props.onRead(codes[0].value);
    },
  });

  useEffect(() => {
    // exception case
    setRefresh(!refresh);
  }, [device, hasPermission]);

  useEffect(() => {
    const requestCameraPermission = async () => {
      const permission = await Camera.requestCameraPermission();
      console.log("Camera.requestCameraPermission ", permission);
      setHasPermission(permission === "granted");
    };

    requestCameraPermission();

    //if it is idle for 15 secs, it will be closed
    setTimeout(() => {
      props.onRead(null);
    }, 15 * 1000);
  }, []);

  if (device == null || !hasPermission) {
    return (
      <View style={styles.page2}>
        <Text style={{ backgroundColor: "white" }}>
          Camera not available or not permitted
        </Text>
      </View>
    );
  }

  return (
    <View style={styles.page2}>
      <Camera
        codeScanner={codeScanner}
        style={StyleSheet.absoluteFill}
        device={device}
        isActive={true}
      />
      <View style={styles.backHeader}>
        <TouchableOpacity
          style={{ padding: 10 }}
          onPress={() => {
            props.onRead(null);
          }}
        >
          <Ionicons name={"arrow-back-outline"} size={25} color={"snow"} />
        </TouchableOpacity>
      </View>
      <View style={styles.footer}>
        <TouchableOpacity
          style={{
            paddingVertical: 8,
            paddingHorizontal: 10,
            borderWidth: 1,
            borderRadius: 5,
            borderColor: "snow",
            alignItems: "center",
          }}
          onPress={() => {
            props.onRead(null);
          }}
        >
          <Text style={{ color: "snow", fontSize: 14 }}>Close</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

export default QRScanner;

const styles = StyleSheet.create({
  page2: {
    flex: 1,
    position: "absolute",
    top: 0,
    width: 0,
    height: "100%",
    width: "100%",
    alignItems: "center",
    justifyContent: "center",
  },
  backHeader: {
    backgroundColor: "#00000090",
    position: "absolute",
    top: 0,
    left: 0,
    right: 0,
    padding: "2%",
    height: "5%",
    width: "100%",
    alignItems: "flex-start",
    justifyContent: "center",
  },
  footer: {
    backgroundColor: "#00000090",
    position: "absolute",
    bottom: 0,
    left: 0,
    right: 0,
    padding: "10%",
    height: "20%",
    width: "100%",
    alignItems: "center",
    justifyContent: "center",
  },
});

Enter fullscreen mode Exit fullscreen mode

Image description

On Success

Image description

Thank you.

Source code here

Tags: #javascript, #react, #react-native, #android, #ios, #qrcode, #qrscan, #qrread, #mobile

Sentry blog image

The Visual Studio App Center’s retiring

But sadly….you’re not. See how to make the switch to Sentry for all your crash reporting needs.

Read more

Top comments (4)

Collapse
 
astrodog-joshh profile image
Josh Salbury

The react-native-vision-camera package is a good open-source solution. However, if you're looking for advanced scanning functionalities, I'd recommend looking into commercial solutions. There is a significant difference in performance (speed, reliability) and developer support.

Full transparency: I work for Scanbot SDK. A colleague of mine recently wrote a barcode tutorial comparing Zxing and our own SDK. I'll link it here in case anyone is interested!

Collapse
 
raguram90 profile image
RamR

ok josh, i'll check this and give my feedback

Collapse
 
nghiem_nguyenle profile image
Nghiem Nguyen Le

I'm getting suck with this meanwhile midnight. Thanks for saving my life and sleeping time!

Collapse
 
raguram90 profile image
RamR

i am glad

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay