This Sendbird Calls Quickstart for React-Native can be used to initialize, configure, and build voice and video calling functionality into your React-Native client app. In this readme, you will find the steps you need to take before implementing the Calls SDK into a project, as well as a sample app that contains the code for implementing voice and video calling features.
Find out more about Sendbird Calls for React-Native on Calls for React-Native doc. If you need any help in resolving any issues or have questions, visit our community.
This section outlines the prerequsites for building a sample app using Sendbird Calls for React-Native.
The minimum requirements for Sendbird Calls Quickstart for React-Native are as follows:
- React-Native 0.65.0+
- yarn 3.6.4
- Xcode 15.0+
- Android Studio
- Physical device (Android 21+, iOS 12+)
- Sendbird Calls SDK for iOS
- Sendbird Calls SDK for Android
Install dependencies (node_modules
and Pods
)
$ yarn install
$ npx pod-install
These steps detail how to set up the backend for a Sendbird-enabled application.
- Login or Sign-up for an account on Sendbird Dashboard.
- Create or select a calls-enabled application on the dashboard.
- Note your Sendbird application ID for future reference.
- On the Sendbird dashboard, navigate to the Users menu.
- Create at least two new users: one as a
caller
, and the other as acallee
. - Note the
user_id
of each user for future reference.
To link your sample React-Native app to the Sendbird application specified in the previous steps, your newly created Sendbird application ID must be included in the code base. In the sample client app’s source code, replace SAMPLE_APP_ID
with the application id generated in the first step.
SendbirdCalls.initialize('SAMPLE_APP_ID');
- To enable push notifications, replace the
applicationId
(Android Studio) and thebundleId
(XCode) with the values from your own project. - Download your project’s
google-services.json
from Google Firebase, and replace the default one with it.
- Open IDE (Xcode or Android Studio)
- Build and run the sample app on your device.
- Install the application onto at least two separate devices for each test created previously.
- If two devices are available, repeat these steps to install the sample app on each device.
FCM Push Notification enables receiving calls even when the app is in the background or in the terminated state.
To make and receive calls, authenticate the user with Sendbird server with the authenticate()
method and register a FCM push token to Sendbird server.
You can register a VoIP push token (specific, the current user’s) by passing it as an argument to a parameter either in the authenticate()
method during authentication, or in the registerPushToken()
method after completing the authentication.
Furthermore, a valid FCM credential(Server Key) needs to be registered on the Sendbird Dashboard which you can do so on Add certificate under Application > Settings > Calls > Notifications.
More about server key
For more details about generating server key, refer to How to Generate a FCM Server Key for Push Notification.
VoIP Push Notification enables receiving calls even when the app is in the background or in the terminated state.
To make and receive calls, authenticate the user with Sendbird server with the authenticate()
method and register a VoIP push token to Sendbird server.
You can register a VoIP push token (specific, the current user’s) by passing it as an argument to a parameter either in the authenticate()
method during authentication, or in the ios_registerVoIPPushToken()
method after completing the authentication.
Furthermore, a valid VoIP Services certificate or Apple Push Notification Service certificate also needs to be registered on the Sendbird Dashboard which you can do so on Add certificate under Application > Settings > Calls > Notifications.
More about certificates
For more details about generating certificates, refer to How to Generate a Certificate for VoIP Push Notification.
- Log in to the sample app on the primary device with the user ID set as the
caller
. - Log in to the sample app on the secondary device using the ID of the user set as the
callee
. Alternatively, you can also use the Calls widget found on the Calls dashboard to log in as thecallee
. - On the primary device, specify the user ID of the
callee
and initiate a call. - If all steps are followed correctly, an incoming call notification will appear on the device of the
callee
. - Reverse the roles. Initiate a call from the other device.
- If the two testing devices are near each other, use headphones to make a call to prevent audio feedback.
You can use different sound effects to enhance the user experience for events that take place while using Sendbird Calls.
To add sound effects, use the SendBirdCall.addDirectCallSound(:forType:) method for the following events: dialing, ringing, reconnecting, and reconnected. Remember to set sound effects before the mentioned events occur. To remove sound effects, use the SendBirdCall.removeDirectCallSound(:forType:) method.
// Play on a caller’s side when making a call.
SendbirdCalls.addDirectCallSound(SoundType.DIALING, 'dialing.mp3');
// Play on a callee’s side when receiving a call.
SendbirdCalls.addDirectCallSound(SoundType.RINGING, 'ringing.mp3');
// Play when a connection is lost, but the SDK immediately attempts to reconnect.
SendbirdCalls.addDirectCallSound(SoundType.RECONNECTING, 'reconnecting.mp3');
// Play when the connection is re-established.
SendbirdCalls.addDirectCallSound(SoundType.RECONNECTED, 'reconnected.mp3');
If you’re using Apple’s CallKit framework, use ringtoneSound instead to add sound effects as ringtones. For example:
RNCallKeep.setup({
ios: {
// ...
ringtoneSound: 'ringing.mp3',
},
});
For more information about sound effects, see the Sendbird Calls iOS Quickstart README for Sound effects.
You can either handle Remote Message on the Native side,
or you can use react-native-firebase
to handle it in Javascript.
// java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
...
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
SendBirdCall.handleFirebaseMessageData(remoteMessage.getData())
}
}
or
// typescript
messaging().setBackgroundMessageHandler(async (message: FirebaseMessagingTypes.RemoteMessage) => {
SendbirdCalls.android_handleFirebaseMessageData(message.data);
});
Handle notifications natively.
import headers to AppDelegate.m
(or AppDelegate.mm
)
#import <CoreMedia/CoreMedia.h>
#import <WebRTC/WebRTC.h>
#import <PushKit/PushKit.h>
#import <AVKit/AVKit.h>
#import <SendBirdCalls/SendBirdCalls-Swift.h>
Before starting, install native modules for using CallKit
and PushKit
.
At this moment, we are using react-native-voip-push-notification
and react-native-callkeep
implement PKPushRegistryDelegate
to AppDelegate.h
#import <PushKit/PushKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, PKPushRegistryDelegate>
implement Delegate methods to AppDelegate.m
#import <RNVoipPushNotificationManager.h>
#import <RNCallKeep.h>
// ...
// ...
// MARK: - VoIP Notification - Receive token
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)pushCredentials forType:(PKPushType)type
{
[RNVoipPushNotificationManager didUpdatePushCredentials:pushCredentials forType:(NSString *)type];
}
// MARK: - VoIP Notification - Receive token
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)pushCredentials forType:(PKPushType)type
{
[RNVoipPushNotificationManager didUpdatePushCredentials:pushCredentials forType:(NSString *)type];
}
// MARK: - VoIP Notification - Receive incoming call
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)())completion
{
// WARN: If you don't report to CallKit, the app will be shut down.
[SBCSendBirdCall pushRegistry:registry didReceiveIncomingPushWith:payload for:type completionHandler:^(NSUUID * _Nullable uuid) {
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];
}
}];
}
didReceiveIncomingPushWithPayload
is called after voip registration, so you should register voip on the JS side, afterSendbirdCalls.initialize
,SendbirdCallListener.onRinging
andRNCallKeep.addListener
- voip notification wake your app
- [Native] App started >> DO NOT CALL [RNVoipPushNotificationManager voipRegistration] on launch in AppDelegate, it will trigger didReceiveIncomingPushWithPayload before sdk initializing
- [JS] JS bridge created and your React-Native app is mounted
- [JS] run SendbirdCalls.initialize()
- [JS] set SendbirdCalls.setListener({onRinging})
- [JS] set RNCallKeep.addListener(...)
- [JS] run RNVoipPushNotification.registerVoipToken() -> it will trigger step 7
- [Native] didReceiveIncomingPushWithPayload called -> it will trigger step 8
- [Native] [SBCSendBirdCall didReceiveIncomingPushWith] called >> it will trigger onRinging event
- [Native] report to CallKit
- [JS] onRinging listener called
Implement didReceiveRemoteNotification
to AppDelegate.m
Note
By default, application(_:didReceiveRemoteNotification:fetchCompletionHandler:) delegate method isn’t called if the client app is in the background or closed. When a remote push notification is delivered to the mobile device, the notification will show as a banner and won’t trigger the delegate method while the app is in the background. If the client app is closed, the payload will be delivered when the user responds to the notification by tapping on it. However, if the client app is in the foreground, the notification will trigger the delegate method immediately.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[SBCSendBirdCall application:application didReceiveRemoteNotification:userInfo];
}
For further detail on Sendbird Calls functions, please refer to Sendbird Calls SDK documentation for iOS and Android.