react-native-webrtc / react-native-callkeep

iOS CallKit framework and Android ConnectionService for React Native
ISC License
909 stars 438 forks source link

[Android] - Cannot speak or listen after initiating a call while the app has exited #737

Closed MacDinhThanh closed 11 months ago

MacDinhThanh commented 11 months ago

Bug report

Description

I am having problem of not speaking and hearing when I have answered a call when a call comes in and my app is exiting via react-native-firebase's setBackgroundMessageHandler

/**
 * @format
 */

import {AppRegistry, PermissionsAndroid, Platform} from 'react-native';
import App from './src';
import {name as appName} from './app.json';
import 'src/helpers/ignoreWarnings';
import messaging from '@react-native-firebase/messaging';
import RNCallKeep from 'react-native-callkeep';
import {
  apolloClient,
  appSetAuthToken,
  fetchAccessToken,
  ZIM_TOKEN,
} from './src/services/apolloClient';
import {GET_MEETING_SESSION} from './src/schemas/queries/meeting';
import {
  ACCEPT_CALL_MEETING,
  END_CALL_MEETING,
  REJECT_CALL_MEETING,
} from './src/schemas/mutations/meeting';
import {NativeFunction} from './src/utils/nativeFunction';
import {Session_Status} from './src/types/graphql-types';
messaging().setBackgroundMessageHandler(async notification => {
  return startCallFromBackgroundAndroid(notification.data);
});
async function backgroundMessageHandler() {
  await RNCallKeep.setup({
    ios: {
      appName: 'ZIM Work',
    },
    android: {
      alertTitle: 'Permissions required',
      alertDescription: 'This application needs to access your phone accounts',
      cancelButton: 'Cancel',
      okButton: 'ok',
      additionalPermissions: [],
    },
  });
  await RNCallKeep.registerAndroidEvents();
  await RNCallKeep.setAvailable(true);
}
const startCallFromBackgroundAndroid = async payload => {
  if (Platform.OS === 'android') {
    fetchAccessToken().then(async data => {
      if (ZIM_TOKEN) {
        await appSetAuthToken(ZIM_TOKEN);
      }
      const failed = data === undefined || data?.token === undefined;
      if (failed) {
        //Log out app
        console.log('can not fetch token');
      } else {
        console.log(data?.token);
        await appSetAuthToken(data?.token);
        const {
          data: {findCurrentSessionInConversation},
        } = await apolloClient.query({
          query: GET_MEETING_SESSION,
          variables: {
            conversationId: payload?.conversationId,
          },
        });
        const {session, attendee} = findCurrentSessionInConversation;
        if (session) {
          RNCallKeep.displayIncomingCall(
            payload?.uuid,
            payload?.callerName,
            payload?.callerName || 'Unknown',
            'number',
            false,
            null,
          );
          RNCallKeep.addEventListener('answerCall', () => {
            RNCallKeep.answerIncomingCall(payload?.uuid);
            RNCallKeep.setCurrentCallActive(session?.meetingInfo.MeetingId);
            apolloClient.mutate({
              mutation: ACCEPT_CALL_MEETING,
              variables: {
                acceptCallInput: {
                  sessionId: session?.id,
                },
              },
            });
            NativeFunction.startMeeting(
              session?.meetingInfo,
              attendee?.attendeeInfo,
            );
          });
          RNCallKeep.addEventListener('endCall', async () => {
            const {
              data: {
                findCurrentSessionInConversation:
                  findCurrentSessionInConversationEndCall,
              },
            } = await apolloClient.query({
              query: GET_MEETING_SESSION,
              variables: {
                conversationId: payload?.conversationId,
              },
            });
            const {session: sessionForEndCall} =
              findCurrentSessionInConversationEndCall;
            console.log(sessionForEndCall);
            if (sessionForEndCall.status === Session_Status.InSession) {
              await apolloClient.mutate({
                mutation: END_CALL_MEETING,
                variables: {
                  endCallInput: {
                    sessionId: session?.id,
                  },
                },
              });
            } else {
              await apolloClient.mutate({
                mutation: REJECT_CALL_MEETING,
                variables: {
                  rejectCallInput: {
                    sessionId: session?.id,
                  },
                },
              });
            }
          });
        }
      }
    });
  }
};
AppRegistry.registerComponent(appName, () => App);
AppRegistry.registerHeadlessTask(
  'RNFirebaseBackgroundMessage',
  backgroundMessageHandler,
);

Versions

- Callkeep:
- React Native:
- iOS:
- Android:
- Phone model: 

Logs

Paste here