I’m trying to record user voice
and transform it to text in react-native app, using expo
, typescript
, and @react-native-voice/voice
package.
I have imported the library into my project, but when I try to launch the start
or stop
function, I get below errors:
TypeError: Cannot read property 'startSpeech' of null
TypeError: Cannot read property 'stopSpeech' of null
I have tried everything, but I don’t understand why the library doesn’t seem to load correctly…
I am using Android 13
. Perhaps there is a version incompatibility?
Please help, i dont find any solutions…
Here’s the code for voice recording:
import React, { useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import Voice from '@react-native-voice/voice';
const SpeechToText = () => {
const [isRecording, setIsRecording] = useState(false);
const [speechText, setSpeechText] = useState('');
const onSpeechStartHandler = () => {
setIsRecording(true);
setSpeechText('');
};
const onSpeechEndHandler = () => {
setIsRecording(false);
};
const onSpeechResultsHandler = (event: any) => {
setSpeechText(event.value[0]);
};
const startSpeechToText = async () => {
try {
await Voice.start('en-US');
onSpeechStartHandler();
} catch (error) {
console.log(error);
}
};
const stopSpeechToText = async () => {
try {
await Voice.stop();
onSpeechEndHandler();
} catch (error) {
console.log(error);
}
};
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.button}
onPressIn={startSpeechToText}
onPressOut={stopSpeechToText}
disabled={isRecording}
>
<Text style={styles.text}>Press and hold to speak</Text>
</TouchableOpacity>
<Text style={styles.speechText}>{speechText}</Text>
</View>
);
};
In app.json
, here is my configuration:
{
"expo": {
[....]
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"permissions": [
"android.permission.RECORD_AUDIO"
]
},
"plugins": [
[
"@react-native-voice/voice",
{
"microphonePermission": "CUSTOM: Allow $(PRODUCT_NAME) to access the microphone",
"speechRecognitionPermission": "CUSTOM: Allow $(PRODUCT_NAME) to securely recognize user speech"
}
]
]
}
}
here is my package.json:
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"test": "jest --watchAll"
},
"dependencies": {
"@react-native-voice/voice": "^3.2.4",
"expo": "~48.0.11",
"expo-font": "~11.1.1",
"expo-linking": "~4.0.1",
"expo-permissions": "^14.1.1",
"expo-router": "^1.5.2",
"expo-speech": "^11.1.1",
"expo-splash-screen": "~0.18.1",
"expo-status-bar": "~1.4.4",
"expo-system-ui": "~2.2.1",
"expo-web-browser": "~12.1.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.71.6",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-safe-area-context": "4.5.0",
"react-native-screens": "~3.20.0",
"react-native-vector-icons": "^9.2.0",
"react-native-web": "~0.18.10"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@types/react": "~18.0.14",
"@types/react-native": "^0.71.5",
"react-test-renderer": "18.2.0",
"typescript": "^4.9.4"
},
"private": true
}```
2
Answers
The import statement for the Voice module is missing a default import. Instead of:
it should be:
This is because the Voice module exports a default object with a Voice property, so we need to import that specific property. The dist/voice path specifies the file where the Voice property is defined.
Also, the onSpeechResultsHandler function assumes that the event object has a value property, which might not be the case. To avoid potential errors, we can use optional chaining to check if the property exists:
This sets the speechText state to the first item in the value array, or an empty string if the value property or the first item in the array is undefined.
The error message suggests that the Voice module is not initialized properly or is not available at the time of calling the startSpeechToText and stopSpeechToText functions. This can happen if the Voice module is not imported correctly or if it is not yet loaded when these functions are called.
To fix this issue, you can try the following:
Make sure that the @react-native-voice/voice package is installed and imported correctly. You can check the package.json file to see if the package is listed as a dependency, and check the import statement to make sure that it is spelled correctly.
Ensure that the Voice module is loaded before calling the startSpeechToText and stopSpeechToText functions. You can add a check to see if the Voice module is loaded before calling these functions, like this:
This checks if the Voice module exists before calling the start and stop methods.
Hope it helps.
It’s not the import, your original import was fine (
) You are using native library modules (such as Microphone access), so it’s not going to work in expo or an emulator straight out of the box. You will need to run in development mode. For android using your mobile phone:
It should now work as expected.