Production-grade WebRTC voice calling SDK for React Native with Firebase signaling, CallKeep UI, VoIP push, metered billing, and auto-reconnect.
npm install @nzmedet/voice-sdkProduction-grade WebRTC voice calling SDK for React Native with Firebase signaling, CallKeep UI, VoIP push, metered billing, and auto-reconnect.
As of v1.0.6+, the SDK uses React Context instead of global variables. You must wrap your app with VoiceSDKProvider after initialization. See the Setup section below for details.
``bash`
npm install @nzmedet/voice-sdk
This package requires the following peer dependencies:
`bash`
npm install react react-native @react-native-firebase/app @react-native-firebase/firestore react-native-webrtc react-native-callkeep react-native-pushkit
`typescript
import { VoiceSDK, VoiceSDKProvider } from 'voice-sdk';
// Initialize @react-native-firebase/app first
// initializeApp();
// Initialize the SDK
await VoiceSDK.init({
appName: 'MyApp',
turnServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{
urls: 'turn:your-turn-server.com:3478',
username: 'your-username',
credential: 'your-password',
},
],
callbacks: {
// Optional: Store push tokens in your database
onTokenUpdate: async (platform, token) => {
// Store token in your backend
},
// Optional: Client-side call event handlers
onCallStarted: async (callId, callerId, calleeId) => {
// Client-side logic when call starts
},
onCallStateChanged: async (callId, state) => {
// Client-side logic when call state changes
},
onCallEnded: async (callId, startTime, endTime) => {
// Client-side logic when call ends
// Note: For server-side billing, implement Cloud Functions
},
},
});
`
Important: The SDK uses React Context to provide functionality to hooks. You must wrap your app with VoiceSDKProvider after initialization:
`typescript
import React from 'react';
import { VoiceSDK, VoiceSDKProvider } from 'voice-sdk';
function App() {
const [initialized, setInitialized] = React.useState(false);
React.useEffect(() => {
VoiceSDK.init({
appName: 'MyApp',
turnServers: [/ ... /],
})
.then(() => {
setInitialized(true);
VoiceSDK.enableDebugMode(); // Optional
})
.catch((error) => {
console.error('Failed to initialize VoiceSDK:', error);
});
}, []);
if (!initialized) {
return
}
// Wrap your app with VoiceSDKProvider
return (
);
}
`
Why? The SDK uses React Context instead of global variables for better React patterns, type safety, and testability. The useCall() and useIncomingCall() hooks require this provider to function.
`typescript`
VoiceSDK.enableDebugMode();
The SDK automatically handles VoIP push token registration (iOS) and FCM token registration (Android). Tokens are automatically received and passed to your onTokenUpdate callback, where you should store them in your database.
Note: Components using hooks must be within a VoiceSDKProvider.
`typescript
import { useCall } from 'voice-sdk';
function MyComponent() {
// This component must be rendered within
const { startCall, callState, isConnected, endCall } = useCall();
const handleCall = async () => {
try {
await startCall('callee-user-id');
} catch (error) {
console.error('Failed to start call:', error);
}
};
return (
<>
>
);
}
`
Note: Components using hooks must be within a VoiceSDKProvider.
`typescript
import { useIncomingCall } from 'voice-sdk';
function IncomingCallComponent() {
// This component must be rendered within
const { incomingCall, answer, decline, getCallMetadata } = useIncomingCall();
if (incomingCall) {
// Access participant info
const caller = incomingCall.caller;
const callee = incomingCall.callee;
// Or get full metadata including any backend-provided fields
const metadata = getCallMetadata(incomingCall.callId);
return (
{caller.photoURL &&
);
}
return null;
}
`
`typescript
import { IncomingCallScreen, ActiveCallScreen } from 'voice-sdk';
// In your navigation
component={IncomingCallScreen}
/>
component={ActiveCallScreen}
/>
`
Deploy the included Firestore rules:
`bash`
firebase deploy --only firestore:rules
Important: This SDK does NOT include complete Cloud Functions. You must implement your own Cloud Functions to handle:
- Call Initiation: Creating call records, sending push notifications, validation
- Call Termination: Processing ended calls, calculating duration
- Billing: Calculating costs, updating user balances, processing payments (Stripe, etc.)
- Cleanup: Removing stale calls, handling abandoned calls
The SDK provides reusable helper functions that you can import into your own Cloud Functions. See firebase/functions/README.md for documentation and usage examples.
You are responsible for:
- Implementing your own Cloud Functions based on your requirements
- Setting up your billing logic (Stripe, in-app purchases, subscription models, etc.)
- Defining your database schema and collection structure
- Implementing authentication, authorization, and security rules
- Customizing push notification delivery
Copy the helper utilities to your Firebase Functions project:
`bash`
mkdir -p your-firebase-project/functions/utils
cp firebase/functions/utils/callHelpers.ts your-firebase-project/functions/utils/
When sending push notifications to trigger incoming calls, use this structure:
`json`
{
"callId": "call-uuid-123",
"caller": {
"id": "user-123",
"displayName": "John Doe",
"photoURL": "https://example.com/photo.jpg"
// Backend can add additional fields here
},
"callee": {
"id": "user-456",
"displayName": "Jane Smith",
"photoURL": "https://example.com/jane.jpg"
},
// Optional: additional metadata
"metadata": {
"customField": "value"
}
}
The caller and callee objects can be sent as:
- Direct JSON objects in the data payload
- JSON strings that will be parsed
`json`
{
"callId": "call-uuid-123",
"caller": "{\"id\":\"user-123\",\"displayName\":\"John Doe\",\"photoURL\":\"https://example.com/photo.jpg\"}",
"callee": "{\"id\":\"user-456\",\"displayName\":\"Jane Smith\"}"
}
Important: The SDK expects exactly id, displayName, and photoURL (optional) fields in CallParticipant objects. No backward compatibility for flattened fields like callerId, callerName`, etc.
- ✅ WebRTC voice calling with auto-reconnect
- ✅ Firebase Cloud Firestore signaling
- ✅ CallKeep integration for native call UI
- ✅ VoIP push notifications (iOS)
- ✅ FCM push notifications (Android)
- ✅ Call metadata storage (no backend refetch needed)
- ✅ Billing helpers (you implement your own billing logic)
- ✅ TypeScript support
- ✅ React hooks API
MIT