Errors with reactNative/voice in expo - react-native

thats my code
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, Button, View } from 'react-native';
import { useEffect, useState } from 'react';
import Voice from '#react-native-voice/voice';
export default function App() {
let [started, setStarted] = useState(false);
let [results, setResults] = useState([]);
useEffect(() => {
Voice.onSpeechError = onSpeechError;
Voice.onSpeechResults = onSpeechResults;
return () => {
Voice.destroy().then(Voice.removeAllListeners);
}
}, []);
const startSpeechToText = async () => {
await Voice.start();
setStarted(true);
};
const stopSpeechToText = async () => {
await Voice.stop();
setStarted(false);
};
const onSpeechResults = (result) => {
setResults(result.value);
};
const onSpeechError = (error) => {
console.log(error);
};
return (
<View style={styles.container}>
{!started ? <Button title='Start Speech to Text' onPress={startSpeechToText} /> : undefined}
{started ? <Button title='Stop Speech to Text' onPress={stopSpeechToText} /> : undefined}
{results.map((result, index) => <Text key={index}>{result}</Text>)}
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
when I run it I keep getting this error
[Unhandled promise rejection: TypeError: null is not an object (evaluating 'Voice.startSpeech')]
I tried asking chatGPT but he can't answer it
Packages and import is correct, so I don't know what the error is nor how I can fix it

Check if it works on another version of android, I launched some emulators and it seems that below Android 12 there are problems with Permissions.
On Android 12 and above, my code with react-native-voice works well with expo run:android but I can't find out why once built with expo build:android I still have problems with mic permissions

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

React Native - searchApi is not a function

I am new in React Native. I try to create a simple searching food restaurant with Yelp. Unfortunately, I get an error:
"searchApi is not a function. (in 'searchApi(term)', 'searchApi' is
"")
Below my code.
useResults.js
import React, { useEffect, useState } from 'react';
import yelp from '../api/yelp';
export default () => {
const [result, setResult] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const searchApi = async (searchTerm) => {
console.log("hi there");
try {
const response = await yelp.get('/search', {
params: {
limit: 50,
term: searchTerm,
location: 'san jose'
}
});
setErrorMessage(null);
setResult(response.data.businesses);
} catch (err) {
setErrorMessage('Something Went Wrong');
}
};
/*
useEffect(() => {}); //Run the arrow function everytime the component is rendered
useEffect(() => {}, []); // Run the arrow function only when the component is first rendered
useEffect(() => {}, [value]); // Run the arrow function only when the component is first rendered, and when the value is changes
*/
useEffect(() => {
searchApi('pasta');
}, []);
return [searchApi, result, errorMessage];
};
SearchScreen.js
import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import ResultList from '../components/ResultList';
import SearchBar from '../components/SearchBar';
import useResults from '../hooks/useResults';
const SearchScreen = () => {
const [term, setTerm] = useState('');
const [searchApi, result, errorMessage] = useResults();
console.log(result);
return (
<View>
<SearchBar
term={term}
onTermChange={setTerm}
onTermSubmit={() => searchApi(term)}
/>
<View>{errorMessage ? <Text>{errorMessage}</Text> : null}</View>
<Text>We have found {result.length} results</Text>
<ResultList title="Cost Effective" />
<ResultList title="Bit Pricier" />
<ResultList title="Big Spender"/>
</View>
);
};
const styles = StyleSheet.create({
});
export default SearchScreen;
edit :
SearchBar.js
import React from 'react';
import { View, Text, StyleSheet, TextInput } from 'react-native';
import { Feather } from '#expo/vector-icons';
const SearchBar = ({ term, onTermChange, onTermSubmit }) => {
return (
<View style={styles.backgroundStyle}>
<Feather style={styles.iconStyle} name="search" size={30} color="black" />
<TextInput style={styles.inputStyle}
autoCapitalize="none"
autoCorrect={false}
placeholder="Search"
value={term}
onChangeText={onTermChange}
onEndEditing={onTermSubmit}
/>
</View>
)
};
const styles = StyleSheet.create({
backgroundStyle: {
marginTop: 10,
backgroundColor: '#F0EEEE',
height: 50,
borderRadius: 5,
marginHorizontal: 15,
flexDirection: 'row'
},
inputStyle: {
flex: 1,
fontSize: 18,
marginHorizontal: 10
},
iconStyle: {
fontSize: 35,
alignSelf: 'center'
}
});
export default SearchBar;
When I type in search bar and hit done button, I got the error above.
Seems in useResults.js file this: return [searchApi, result, errorMessage]; does not properly return the function. But the result and errorMessage return successfully.
And in this file: SearchScreen.js the error line is shown in here: onTermSubmit={() => searchApi(term)}.
How to fix this?
Try adding a callback to onChangeText.
<TextInput style={styles.inputStyle}
autoCapitalize="none"
autoCorrect={false}
placeholder="Search"
value={term}
onChangeText={() => onTermChange()} // Add fat arrow function here
onEndEditing={onTermSubmit}
/>

react-native-image-crop-tools CropView not showing image to be cropped

I am using react-native-image-crop-tools for cropping the image but CropView not showing the image to be cropped only a blank screen is showing. any solution regarding this?
import { CropView } from 'react-native-image-crop-tools';
const [uri, setUri] = useState('https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg');
{uri !== undefined && <CropView
sourceUrl={uri}
style={{flex:1}}
ref={cropViewRef}
onImageCrop={(res) => console.warn(res)}
keepAspectRatio
aspectRatio={{ width: 16, height: 9 }}
/>}
Try this, I hope it will help you.
app.js
import React, { useState, useRef } from 'react';
import { Button, StyleSheet, View} from 'react-native';
import { CropView } from 'react-native-image-crop-tools';
import { launchImageLibrary } from 'react-native-image-picker';
export default function app() {
const [uri, setUri] = useState();
const cropViewRef = useRef();
let options = {
mediaType: 'photo',
quality: 1,
};
return (
<>
<View style={styles.container}>
<Button
title={'Pick Image'}
onPress={() => {
launchImageLibrary(options, response => {
setUri(response.assets[0].uri);
});
}}
/>
{uri !== undefined && <CropView
sourceUrl={uri}
style={styles.cropView}
ref={cropViewRef}
onImageCrop={(res) => console.log(res)}
keepAspectRatio
aspectRatio={{ width: 16, height: 9 }}
/>}
<Button
title={'Get Cropped View'}
onPress={() => {
cropViewRef.current.saveImage(true, 100);
}}
/>
</View>
</>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
cropView: {
flex: 1,
backgroundColor: '#000'
},
});
The library doesn't support remote images. It working in iOS is merely coincidental as might the native ios library supports for the cropping of network images.
If you want to crop a remote image please download it first using RNFetchBlob and then pass the local file path to it.
Supporting remote images directly is a somewhat complicated task and out of scope for this project.
You also can check out the closed issue in the library.
https://github.com/hhunaid/react-native-image-crop-tools/issues/16
You can have a try with the below example to crop the network images in the android platform:
For ex:
import React, {useCallback, useEffect, useState} from 'react';
import {View, Text} from 'react-native';
import {CropView} from 'react-native-image-crop-tools';
import RNFetchBlob from 'rn-fetch-blob';
export default () => {
const [uri, setUri] = useState('');
const getImage = useCallback(() => {
try {
RNFetchBlob.config({
fileCache: true,
// by adding this option, the temp files will have a file extension
appendExt: 'png',
})
.fetch(
'GET',
'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg',
)
.then(res => {
let status = res.info().status;
if (status === 200) {
setUri('file://' + res.path());
} else {
console.log(status);
}
})
// Something went wrong:
.catch((errorMessage, statusCode) => {
// error handling
console.log('Error : ', errorMessage);
});
} catch (err) {
console.log('Error : ', err.message);
}
}, []);
useEffect(() => {
getImage();
}, [getImage]);
if (uri === '') {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>{'processing...'}</Text>
</View>
);
}
return (
<CropView
sourceUrl={uri}
style={{flex: 1, height: '100%', width: '100%'}}
// ref={cropViewRef}
onImageCrop={res => console.warn(res)}
keepAspectRatio
aspectRatio={{width: 16, height: 9}}
/>
);
};

Amplify Tutorial (Expo) and got error message on signin

I'm doing this tutorial: https://docs.amplify.aws/start/getting-started/auth/q/integration/react-native#create-login-ui
I followed it completely and did everything they told me to do. The Todo works, but when I added Auth, and wrapped it. The project will start. Users can create accounts. But when you try to sign in on iOS it won't work. Strangely, when I tested it on web, users could sign in. Leading me to think it is a problem with iOS. I tested it on my iPhone with expo installed and it failed there too.
Here is a link to my issue: https://github.com/aws-amplify/amplify-js/issues/8113#issuecomment-830995508
This is my app.js
import config from './aws-exports'
Amplify.configure(config)
import { withAuthenticator } from 'aws-amplify-react-native'
import React, { useEffect, useState } from 'react'
import {
View, Text, StyleSheet, TextInput, Button
} from 'react-native'
import { API, graphqlOperation } from 'aws-amplify'
import { createTodo } from './graphql/mutations'
import { listTodos } from './graphql/queries'
const initialState = { name: '', description: '' }
const App = () => {
const [formState, setFormState] = useState(initialState)
const [todos, setTodos] = useState([])
useEffect(() => {
fetchTodos()
}, [])
function setInput(key, value) {
setFormState({ ...formState, [key]: value })
}
async function fetchTodos() {
try {
const todoData = await API.graphql(graphqlOperation(listTodos))
const todos = todoData.data.listTodos.items
setTodos(todos)
} catch (err) { console.log('error fetching todos') }
}
async function addTodo() {
try {
const todo = { ...formState }
setTodos([...todos, todo])
setFormState(initialState)
await API.graphql(graphqlOperation(createTodo, {input: todo}))
} catch (err) {
console.log('error creating todo:', err)
}
}
return (
<View style={styles.container}>
<TextInput
onChangeText={val => setInput('name', val)}
style={styles.input}
value={formState.name}
placeholder="Name"
/>
<TextInput
onChangeText={val => setInput('description', val)}
style={styles.input}
value={formState.description}
placeholder="Description"
/>
<Button title="Create Todo" onPress={addTodo} />
{
todos.map((todo, index) => (
<View key={todo.id ? todo.id : index} style={styles.todo}>
<Text style={styles.todoName}>{todo.name}</Text>
<Text>{todo.description}</Text>
</View>
))
}
</View>
)
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', padding: 20 },
todo: { marginBottom: 15 },
input: { height: 50, backgroundColor: '#ddd', marginBottom: 10, padding: 8 },
todoName: { fontSize: 18 }
})
export default withAuthenticator(App)```
I feel like the problem might be with the ./aws-exports potentially. There was a bug where you had to move it out of src, etc. Anyone have any ideas?
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/1Wt6J.png
I found out that the login error was due to a bug with expo deprecating a file. See this issue for more. https://github.com/aws-amplify/amplify-js/issues/8113#issuecomment-830995508

React Native - How to extract data from FaceDetector of Expo SDK?

I’m new to React Native and still learning React and JavaScript. I’m practicing on Expo snack with Expo's FaceDetector (SDK 37) and managed to generate data about faces. However, I couldn't (or don't know how to) extract these data. My goal for now is to render the rollAngle data in a Text component.
Here is the code I used in Expo Snack and tested with my Android cellphone:
import React, { useState, useEffect } from 'react';
import { Text, View } from 'react-native';
import { Camera } from 'expo-camera';
import * as FaceDetector from 'expo-face-detector'
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [faces, setFaces] = useState([])
const faceDetected = ({faces}) => {
setFaces({faces})
console.log({faces})
}
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission !== true) {
return <Text>No access to camera</Text>
}
return (
//<View style={{ flex: 1 }}>
<Camera
style={{ flex: 1 }}
type='front'
onFacesDetected = {faceDetected}
FaceDetectorSettings = {{
mode: FaceDetector.Constants.Mode.fast,
detectLandmarks: FaceDetector.Constants.Landmarks.all,
runClassifications: FaceDetector.Constants.Classifications.none,
minDetectionInterval: 5000,
tracking: false
}}
>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<Text style= {{top:200}}> is {faces[0].rollAngle} </Text>
</View>
</Camera>
//</View>
);
}
In the snack console, I see results like this:
Results in the Snack console
I tried to replace the faceDetected function with the following code:
const faceDetected = (faces) => {
setFaces(faces)
console.log(faces)
}
Then, the console shows slightly different results: Results in Snack console
I tried both ways to render rollAngle, but an error message showed up and said face[0].rollAngle is undefined and is not an object.
Please help and any suggestion is appreciated.
Thank you.
You may have resolved this problem.
"faces.faces" worked for me..
const faceDetected = (faces) => {
setFaces(faces.faces)
}
I am new to react-native..
So if you resolved it by some other way please let us know.
I believe I have fixed your problem:
import React, { useState, useEffect } from 'react';
import { Text, View } from 'react-native';
import { Camera } from 'expo-camera';
import * as FaceDetector from 'expo-face-detector'
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [faces, setFaces] = useState([])
const faceDetected = ({faces}) => {
setFaces(faces) // instead of setFaces({faces})
console.log({faces})
}
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission !== true) {
return <Text>No access to camera</Text>
}
return (
//<View style={{ flex: 1 }}>
<Camera
style={{ flex: 1 }}
type='front'
onFacesDetected = {faceDetected}
FaceDetectorSettings = {{
mode: FaceDetector.Constants.Mode.fast,
detectLandmarks: FaceDetector.Constants.Landmarks.all,
runClassifications: FaceDetector.Constants.Classifications.none,
minDetectionInterval: 5000,
tracking: false
}}
>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
{faces[0] && <Text style= {{top:200}}> is {faces[0].rollAngle} </Text>} // only render text if faces[0] exists
</View>
</Camera>
//</View>
);
}
I think your main problem was you were using
setFaces({faces})
instead of
setFaces(faces)