Forem

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

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

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

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay