twilio / twilio-voice-react-native-app

Other
38 stars 21 forks source link

[TypeError: Cannot read property 'voice_connect_android' of null] #136

Closed dmitriy-uvin closed 9 months ago

dmitriy-uvin commented 10 months ago

I need to implement ability to make and receive calls from my React Native app. I use React Native in conjunction with Expo. Here is my package.json

{
  "name": "dialer",
  "main": "expo-router/entry",
  "version": "1.0.0",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "test": "jest --watchAll"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@expo/vector-icons": "^14.0.0",
    "@react-native-async-storage/async-storage": "1.21.0",
    "@react-native-picker/picker": "2.6.1",
    "@react-navigation/native": "^6.0.2",
    "@twilio/voice-react-native-sdk": "^1.0.0-beta.4",
    "@twilio/voice-sdk": "^2.10.1",
    "axios": "^1.6.5",
    "dayjs": "^1.11.10",
    "expo": "~50.0.1",
    "expo-av": "~13.10.4",
    "expo-font": "~11.10.2",
    "expo-linking": "~6.2.2",
    "expo-router": "~3.4.3",
    "expo-splash-screen": "~0.26.3",
    "expo-status-bar": "~1.11.1",
    "expo-system-ui": "~2.9.3",
    "expo-web-browser": "~12.8.1",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.49.3",
    "react-native": "0.73.2",
    "react-native-bouncy-checkbox": "^3.0.7",
    "react-native-dotenv": "^3.4.9",
    "react-native-safe-area-context": "4.8.2",
    "react-native-screens": "~3.29.0",
    "react-native-toast-notifications": "^3.4.0",
    "react-native-web": "~0.19.6",
    "twilio": "^4.21.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/axios": "^0.14.0",
    "@types/react": "~18.2.45",
    "jest": "^29.2.1",
    "jest-expo": "~50.0.1",
    "react-test-renderer": "18.2.0",
    "typescript": "^5.1.3"
  },
  "private": true
}

Here is my API that is responsible for generating Access Token with Voice grant:

public async getAccessTokenForCall(userUuid: string): Promise<string> {
    const twilio = require('twilio');
    const AccessToken = twilio.jwt.AccessToken;
    const VoiceGrant = AccessToken.VoiceGrant;
    const voiceGrant = new VoiceGrant({
      outgoingApplicationSid: '<TwilML application SID here>',
      incomingAllow: true,
    });
    const token = new AccessToken(
      this.accountSid,
      this.apiKey,
      this.apiKeySecret,
      {
        identity: userUuid.replaceAll('-', '_'),
      },
    );
    token.addGrant(voiceGrant);
    const jwtValue = token.toJwt();
    return jwtValue;
  }

Here is my method that is responsible for TwilML that is used in TwilML app:

@Post('/ml')
  @Header('Content-Type', 'text/plain')
  public async twilMl(@Req() req: AppRequest) {
    const response = new twiml.VoiceResponse();
    const dial = response.dial({
      answerOnBridge: true,
    });
    dial['number']('+<hardcoded phone number for testing>')
    return response.toString();
  }

React native component that triggers call:

try {
        load();
        const tokenRes: AccessTokenDto = await twilioApi.getVoiceToken();
        const token = tokenRes.accessToken;
        const voice: Voice = new Voice();
        voice.on(Voice.Event.Registered, (data: any) => {
          console.log('registered', data);
        });
        voice.on(Voice.Event.Error, (data) => {
          console.log('voice error', data);
        })
        const call = await voice.connect(token, {
          params: {
            To: phoneNumber,
            recipientType: 'number',
          }
        });
      } catch (e) {
        console.log(e);
      } finally {
        loadEnd();
      }

Important note: event voice.on are not triggered at all.

I receive next error during call init:

[TypeError: Cannot read property 'voice_connect_android' of null]

ANY IDEAS how it can be solved?