How can I display a modal with info from a scanned QR code? - react-native

Tech stack: Expo, React-Native
Using: expo-barcode-scanner
I am trying to create an app that will scan a QR code and then display the info from the QR code on the screen, preferably in a modal so I can display an image.
I've created an app that will do that... except that it uses an alert function to show the text. How can I change it to a modal? When I try to change it to modal, or return a modal it doesn't work.
My code:
import React, { useCallback, useEffect, useState } from 'react';
import { StyleSheet, Text, View, Image, Button, Modal } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
import {createCustomerInformation2} from './src/graphql/mutations'
import logo from './assets/icon.png';
import Scanner from './components/QRScanner';
import custModal from './components/custInfo'
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
// const [modalVisible, setModalVisible] = useState(false);
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
var newData = JSON.parse(data)
// return(
// <View>
// <Modal>
// <View>
// <Text>Test</Text>
// </View>
// </Modal>
// </View>
// )
alert(`
Customer: ${newData.name}
Email: ${newData.email}
Phone: ${newData.phone}
Favorite Drink: ${newData.favoriteDrink}
`);
// createCustomerInformation2(newData)();
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View id="view" style={styles.container}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
// If you want to use the front facing or rear facing, include type={'front'} or put 'back'
/>
{scanned && <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
},
});

Instead of returning that JSX in the onBarCodeScanned handler, you'll need to include it in the returned JSX of your App. You'll want to conditionally hide the modal when no value is present. You'll then populate it by assigning the scanned value to a state variable in the event handler and displaying that value in the modal.

Related

React native expo camera "no access to camera" error

I have installed the expo camera tool with npm.
I run this code and it works on Snack :
import React, { useState, useEffect } from "react";
import { Text, View, StyleSheet, Button } from "react-native";
import { BarCodeScanner } from "expo-barcode-scanner";
import { Camera } from "expo-camera";
export default function Scanner() {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === "granted");
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
alert(`Bar code with type ${type} and data ${data} has been scanned!`);
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={styles.container}>
<Camera
style={StyleSheet.absoluteFillObject}
onBarCodeScanned={console.log}
barCodeScannerSettings={{
barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
}}
/>
{scanned && (
<Button title={"Tap to Scan Again"} onPress={() => setScanned(false)} />
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
justifyContent: "center",
},
});
But in localhost I have the message "no access to camera"and I have no popup asking for access.
I am a complete beginner with react native and I can't figure out how to fix this ^^.
EDIT : I'm running it on web

Invalid hook call. Hooks can only be called inside of the body of a function component. : barcode-scanner

I try to use the barcode-scanner on my react native app, but a I get this error :
Invalid hook call. Hooks can only be called inside of the body of a function component.
That is the code source of my component :
import React, { useState, useEffect, Component } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
class QrCode extends Component {
render () {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
alert(`Bar code with type ${type} and data ${data} has been scanned!`);
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={styles.container}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
{scanned && <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
export default QrCode;

How to create custom camera component using that return image, in react-native

I'm trying to build custom camera component similar to launchCamera in react-native-image-picker module, that can be called from function and returns image. How this can be implemented using react-native-camera. Because I need to add some custom controls in it.
create a new file for camera screen and put it in your navigator, and craete a button to navigate to camera screen, ı also share camera screen code example, you can use without authentication
import React, { useRef, useState, useEffect,useContext } from "react";
import { Camera } from "expo-camera";
import styled from "styled-components/native";
import { View, TouchableOpacity,Text } from "react-native";
import { IconButton, Colors } from 'react-native-paper';
import AsyncStorage from "#react-native-async-storage/async-storage";
import { AuthenticationContext } from "../../../authentication.context";
const ProfileCamera = styled(Camera)`
width: 100%;
height: 100%;
`;
export const CameraScreen = ({navigation}) => {
const [isFront,setFront]=useState(true);
const [hasPermission, setHasPermission] = useState(null);
const cameraRef = useRef();
const {user}=useContext(AuthenticationContext);
const snap = async () => {
if (cameraRef) {
const photo = await cameraRef.current.takePictureAsync();
AsyncStorage.setItem(`${user.uid}-photo`,photo.uri);
navigation.goBack();
}
};
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === "granted");
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<ProfileCamera
style={{alignItems:'center',justifyContent:'flex-end',paddingBottom:16}}
ref={(camera) => (cameraRef.current = camera)} type={isFront? Camera.Constants.Type.front:Camera.Constants.Type.back} ratio={"16:9"}>
<View style={{flexDirection:'row',alignItems:'center'}}>
<IconButton
icon="camera"
color="grey"
size={50}
onPress={snap}
animated={true}
/>
<IconButton
style={{position:'absolute',left:170}}
icon="camera-switch-outline"
color="grey"
size={50}
onPress={()=>setFront(!isFront)}
animated={true}
/>
</View>
</ProfileCamera>
);
};

Expo React Native: BarcodeScanner.requestPermissionsAsync() doesnt apply a permission request

I'm trying to build a Barcode scanner component and I'm using expo-barcode-scanner.
the console.log works fine and I get the ASKING text.
the dialog window doesnt show up
here is my code:
import React, { useState, useEffect } from 'react';
import { Text,SafeAreaView, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
const ScannerComponent =()=> {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const askForCameraPermission = () =>{
console.log('ASKING')
async () => {
const {status} = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
}
}
useEffect(() => {
askForCameraPermission();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
alert(`Bar code with type ${type} and data ${data} has been scanned!`);
};
if (hasPermission === null) {
return (<View style={styles.container}><Text style={styles.text}>Requesting for camera permission</Text></View>);
}
if (hasPermission === false) {
return (<View style={styles.container}><Text style={styles.text}>No access to camera</Text></View>);
}
return (
<SafeAreaView style={styles.container}>
<Text value='hello' />
<View style={styles.scanner}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
</View>
{scanned && <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />}
</SafeAreaView>
);
}
export default ScannerComponent

Change screen without a click event using navigation stack react native

Well what I'm trying to do is when he finishes reading the qr code is to move to the next screen as soon as this event ends. I tried to do this by declaring:
const handleBarCodeScanned = ({ type, data }) => {
{this.props.navigation.navigate ('testScreen', {data1, data2})}
}
Usually, the documentation always shows accompanied by an onClick () function associated with a button.
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button, PermissionsAndroid } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
import wifi from 'react-native-android-wifi';
export default function QrCodeScreen() {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
{this.props.navigation.navigate('nextScreen', { data1, data2 })}//Change screen
})}
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View
style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-end',
}}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
{scanned && <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />}
</View>
);
}
Seems like you're using functional components so there is no this context.
You forget to import and init the navigation hook
import { useNavigation } from '#react-navigation/native';
And
export default function QrCodeScreen() {
const navigation = useNavigation();
...
Then
const handleBarCodeScanned = ({ type, data }) => {
navigation.navigate('nextScreen', { data1, data2 })
})}
I managed to solve the error by passing as the navigation parameter in the function declaration.
Before
export default function QrCodeScreen() {
}
After
export default function QrCodeScreen({navigation}) {
}
Change screen
navigation.navigate('SetupConnectionScreen');