Calls / React Native
Calls React Native v1
Calls React Native
Calls
React Native
Home
/
Calls
/
React Native
/
Direct call

Receive a call in the background

When the client app is in the foreground, incoming call events are received through the server connection. However, when the app is running in the background or closed, incoming calls are received through PushKit for iOS and FCM for Android.


For iOS

To receive PushKit messages delivered to the iOS SDK in the client app, add SendBirdCall.pushRegistry(_:didReceiveIncomingPushWith:for:). For Objective-C, add [SBCSendBirdCall pushRegistry:_ didReceiveIncomingPushWith:for:] instead.

Implement libraries such as React Native Callkeep and React Native VoIP Push Notification to access functionalities CallKit and PushKit provides in the client app.

// AppDelegate.h
#import <PushKit/PushKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, PKPushRegistryDelegate>

// AppDelegate.mm
#import <CoreMedia/CoreMedia.h>
#import <WebRTC/WebRTC.h>
#import <PushKit/PushKit.h>
#import <AVKit/AVKit.h>
#import <SendBirdCalls/SendBirdCalls-Swift.h>
#import <RNCallKeep.h>

// ...

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)())completion
{
  [SBCSendBirdCall pushRegistry:registry didReceiveIncomingPushWith:payload for:type completionHandler:^(NSUUID * _Nullable uuid) {
    // IMPORTANT: Incoming calls MUST be reported when receiving a PushKit push.
    //  If you don't report to CallKit, the app will be terminated.

    if(uuid != nil) {
      // Report valid call
      SBCDirectCall* call = [SBCSendBirdCall callForUUID: uuid];
      [RNCallKeep reportNewIncomingCall: [uuid UUIDString]
                                 handle: [[call remoteUser] userId]
                             handleType: @"generic"
                               hasVideo: [call isVideoCall]
                    localizedCallerName: [[call remoteUser] nickname]
                        supportsHolding: YES
                           supportsDTMF: YES
                       supportsGrouping: YES
                     supportsUngrouping: YES
                            fromPushKit: YES
                                payload: [payload dictionaryPayload]
                  withCompletionHandler: completion];
    } else {
      // Report and end invalid call
      NSUUID* uuid = [NSUUID alloc];
      NSString* uuidString = [uuid UUIDString];

      [RNCallKeep reportNewIncomingCall: uuidString
                                 handle: @"invalid"
                             handleType: @"generic"
                               hasVideo: NO
                    localizedCallerName: @"invalid"
                        supportsHolding: NO
                           supportsDTMF: NO
                       supportsGrouping: NO
                     supportsUngrouping: NO
                            fromPushKit: YES
                                payload: [payload dictionaryPayload]
                  withCompletionHandler: completion];
      [RNCallKeep endCallWithUUID:uuidString reason:1];
    }
  }];
}
SendbirdCalls.setListener({
  async onRinging(callProps) {
    const directCall = await SendbirdCalls.getDirectCall(callProps.callId);

    // Handle an incoming call with CallKit (react-native-callkeep).
    RNCallKeep.addEventListener('answerCall', async () => {
      directCall.accept();
    });
    RNCallKeep.addEventListener('endCall', async () => {
      directCall.end();
    });

    const unsubscribe = directCall.addListener({
      onEnded() {
        RNCallKeep.removeEventListener('answerCall');
        RNCallKeep.removeEventListener('endCall');
        RNCallKeep.endAllCalls();
        unsubscribe();
      },
    });

    RNCallKeep.displayIncomingCall(
      callProps.ios_callUUID,
      callProps.remoteUser?.userId,
      callProps.remoteUser?.nickname ?? 'Unknown',
      'generic',
      callProps.isVideoCall,
    );
  }
})

RNVoipPushNotification.registerVoipToken();

For Android

To receive FCM messages delivered to SendbirdCalls in the React Native SDK, implement the SendbirdCalls.android_handleFirebaseMessageData() method.

import messaging, { FirebaseMessagingTypes } from '@react-native-firebase/messaging';

SendbirdCalls.setListener({
  async onRinging(callProps) {
  const directCall = await SendbirdCalls.getDirectCall(callProps.callId);

  // Handle an incoming call with what you want (e.g. Notifee foreground service, react-native-callkeep).
  }
});

const firebaseListener = async (message: FirebaseMessagingTypes.RemoteMessage) => {
 SendbirdCalls.android_handleFirebaseMessageData(message.data);
};
messaging().setBackgroundMessageHandler(firebaseListener);
messaging().onMessage(firebaseListener);