DEV Community

Dallington Asingwire
Dallington Asingwire

Posted on

How to generate and download QR code in a React Native application

Background:
QR Codes are scannable codes that store data. QR stands for Quick Response. They serve a great purpose in accessing information forexample items in a supermarket have a QR codes that contain product information say item name, date of expiry, details about product manufacturer e.g their phone number etc.

Onto coding🥳
With that background information, let's dig deep into how we can generate and download QR codes in a react native application. First, we need to install 2 dependency packages i.e react-native-svg and react-native-qrcode-svg.
You can use npm or yarn to install the two dependencies under the root directory of your project using the commands below;

npm i -S react-native-svg react-native-qrcode-svg
Enter fullscreen mode Exit fullscreen mode

OR

yarn add react-native-svg react-native-qrcode-svg
Enter fullscreen mode Exit fullscreen mode

Reusable component QRCODE example
In the following example, I create a reusable hook component called QRCODE;

import React from 'react';
import QRCode from 'react-native-qrcode-svg';

const QRCODE = ({value, getRef}) => {
    return(
        <QRCode
        value={value}
        size={250}
        color="black"
        backgroundColor="white"
        getRef={getRef}
        />
        )
    }

export default QRCODE
Enter fullscreen mode Exit fullscreen mode

In the above hook, I import QRCode from react-native-qrcode-svg package. Then the custom reusable hook QRCODE takes in 2 props i.e value & getRef. value is string value of the QR code (When you scan the QR code, value is the information that gets displayed) while getRef is the svg ref of the QR code that can be used further(as we are going to see when downloading/saving this QR code to gallery).

In the return statement, QRCode hook from the dependency, has props i.e value, size, color of the QR code and getRef prop.

Using reusable hook QRCODE
In the following code example, I demonstrate how you can use the reusable hook created above to generate QR Code.

import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import QRCODE from '../components/QRcode';

const App = () => {

  const initialItemState ={
    name: 'Sugar',
    expiryDate: '2023-12-31',
    manufacturer: 'Kakira Sugar Estate'
  }

  const [item, setItem] = useState(initialItemState);
  const [productQRref, setProductQRref] = useState();

  return (
  <View>
   <QRCODE 
      value={JSON.stringify({
       name: item.name,
       expiry: item.expiryDate,
       manufacturer: item.manufacturer
      })}
      getRef={(c) => setProductQRref(c)}/>
  </View>
  )
}
export default App;

const styles = StyleSheet.create({
   container:{
    flex: 1,
    alignItems: 'center'
  }
});
Enter fullscreen mode Exit fullscreen mode

In the above code, I import reusable hook we created before, and then pass properties, values and getRef with their corresponding values. Value is an item with keys; name, expiryDate and manufacturer. Because value prop to QRCODE is a string, I use JSON.stringify to convert item object to a string.

Downloading the generated QR code to Gallery
Well, I talked of useRef as the property passed to QRcode to get svg ref of the QR code.
In that case, I use setProductQRref hook to store the state of the svg ref of the QR code as seen in the above code.

In order to save QR code to gallery, we need two dependencies i.e @react-native-community/cameraroll and react-native-fs. @react-native-community/cameraroll is a react-native native module that provides access to the local camera roll or photo library while react-native-fs is the library that can make you use the filesystem easily in react native.

Code example for saving QR Code to photo gallery

import { 
Platform,
PermissionsAndroid,
ToastAndroid }
 from 'react-native';
import RNFS from "react-native-fs";
import CameraRoll from "@react-native-community/cameraroll";

 const saveQrToDisk = async(item) => {

if (Platform.OS === "android" &&
 !(await hasAndroidPermission())) {
     return;
}

if(productQRref){

productQRref.toDataURL((data) => {

let filePath =  RNFS.CachesDirectoryPath+`/${item.name}.png`;
RNFS.writeFile(filePath, data, 'base64')
  .then((success) => {
    return CameraRoll.save(filePath, 'photo')
  })
 .then(() => {
ToastAndroid.show('QRCode saved to gallery', ToastAndroid.LONG);
          });
   });
   }
 }

const hasAndroidPermission = async() => {
const permission=
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;

  const hasPermission = 
await PermissionsAndroid.check(permission);
  if (hasPermission) {
    return true;
  }

  const status = await PermissionsAndroid.request(permission);
  return status === 'granted';
}
Enter fullscreen mode Exit fullscreen mode

saveQrToDisk is my function name, used to save QR code to gallery, it uses productQRref, the svg ref of the QR code we created in the previous code example. toDataURL function returns returns a data URL containing a representation of the QR code image. The imported RNFS hook writes the filePath of the QR code on the disk. When the path is finally written, I then use CameraRoll.save hook to save the QR code to the created file path on the disk.

hasAndroidPermission hook is used to request permissions to write to phone storage if not enabled.

Full Code example for generating and downloading QR code

import React, { useState } from 'react';
import { View, StyleSheet,Platform, PermissionsAndroid,
         ToastAndroid, Text, TouchableOpacity  } 
from 'react-native';
import QRCODE from '../components/QRcode';
import RNFS from "react-native-fs";
import CameraRoll from "@react-native-community/cameraroll";

const App = () => {

  const initialItemState ={
    name: 'Sugar',
    expiryDate: '2023-12-31',
    manufacturer: 'Kakira Sugar Estate'
  }

  const [item, setItem] = useState(initialItemState);
  const [productQRref, setProductQRref] = useState();

const saveQrToDisk = async() => {

if (Platform.OS === "android" &&
 !(await hasAndroidPermission())) {
     return;
}

if(productQRref){

productQRref.toDataURL((data) => {

let filePath =  RNFS.CachesDirectoryPath+`/${item.name}.png`;
RNFS.writeFile(filePath, data, 'base64')
  .then((success) => {
    return CameraRoll.save(filePath, 'photo')
  })
 .then(() => {
ToastAndroid.show('QRCode saved to gallery', ToastAndroid.LONG);
          });
   });
   }
 }

 const hasAndroidPermission = async() => {
const permission=
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;

  const hasPermission = 
await PermissionsAndroid.check(permission);
  if (hasPermission) {
    return true;
  }

  const status = await PermissionsAndroid.request(permission);
  return status === 'granted';
}

  return (
  <View style={styles.container}>
    <Text style={styles.qrText}>QR Code</Text>
   <QRCODE 
      value={JSON.stringify({
       name: item.name,
       expiry: item.expiryDate,
       manufacturer: item.manufacturer
      })}
      getRef={(c) => setProductQRref(c)}/>
  <TouchableOpacity 
      style={styles.button}
      onPress={() => { saveQrToDisk() }}>
     <Text style={styles.save}>Save to Gallery</Text>
   </TouchableOpacity>
  </View>
  )
}
export default App;

const styles = StyleSheet.create({

  container:{
    flex: 1,
    backgroundColor: '#fff',
    justifyContent: 'center',
    alignItems: 'center'
  },

  button: {
    borderRadius:30,
    padding:15,
    position: 'absolute',
    bottom: 0,
    width: '90%',
    justifyContent: 'center',
    alignItems: 'center',
    fontWeight: 'bold',
    marginBottom: 30,
    color: '#fff',
    backgroundColor:"#273746"
  },

  qrText: {
    top: -20,
    color: '#000',
    fontSize:18,
    fontWeight: 'bold'
  },

  save: {
    color: '#fff',
    fontSize:16,
    textTransform: 'capitalize'
 }
});
Enter fullscreen mode Exit fullscreen mode

Output on your emulator or phone device screen
Output on your emulator or phone device screen

That's how you can generate QR Code and save it to gallery in a react native application. Thank you for reading through this article. Today was a long class, oops!!!😌 But thank you!!🤗

Top comments (2)

Collapse
 
tokkozhin profile image
Daniel Tokkozhin

Now you can try to do this and more with fully customizable rn qr generator 😉github.com/tokkozhin/react-native-...

Collapse
 
yassine1982 profile image
RIAHI Yassine

Thank you for this clean tutorial...
Can you please write code to share the QrCode image ...