skip to Main Content

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


  1. The import statement for the Voice module is missing a default import. Instead of:

    import Voice from '@react-native-voice/voice';
    

    it should be:

    import Voice from '@react-native-voice/voice/dist/voice';
    

    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:

    setSpeechText(event?.value?.[0] || '');
    

    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:

    const startSpeechToText = async () => {
        if (Voice) {
            try {
                await Voice.start('en-US');
                onSpeechStartHandler();
            } catch (error) {
                console.log(error);
            }
        }
    };
    
    const stopSpeechToText = async () => {
        if (Voice) {
            try {
                await Voice.stop();
                onSpeechEndHandler();
            } catch (error) {
                console.log(error);
            }
        }
    };
    

    This checks if the Voice module exists before calling the start and stop methods.

    Hope it helps.

    Login or Signup to reply.
  2. It’s not the import, your original import was fine (

    import Voice from "@react-native-voice/voice";

    ) 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:

    1. From the terminal: eas build –profile development –platform android
    2. From the terminal: npx expo start –dev-client
    3. Scan the QR code with your device

    It should now work as expected.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search