React Native × Node × Twilio (iOS - Android) — Quick Setup Guide
A concise guide for spinning up the project locally. Perfect for new teammates who just need the basics.
Stack: React Native • Node (Express) • Twilio • Firebase • Socket.IO
Targets: iOS (VoIP) • Android (FCM)
Prerequisites
- macOS Sequoia (15) or later with Xcode 16
- Android Studio
- A physical iOS device
- A physical Android device
- Node 22+ - npm 10+
- CocoaPods ≥ 1.14 — brew install cocoapods
- A Twilio account with an active phone number
Download / Clone - Install
Steps
- Download the project.
- Navigate to the project root folder.
- Open it in your editor (VS Code recommended).
Bash
bash# Install deps
npm install
cd ios
pod install
Configure Environment Variables
- Replace BASEURL in src/assets/Helper/revenueCat.tsx (or revenueCat.js). Use the URL from your running Node API or your live server.
- Replace keys in .env for Twilio, Firebase, and Notify (steps below).
- After configuring RevenueCat, paste each platform’s Public API Key into your RevenueCat helper file (revenueCat.tsx/js).
Run the Stack
iOS
Heads-up: The first iOS build triggers CocoaPods; it may take a few minutes.
- Run npm start.
- Open ios/nummio.xcworkspace in Xcode.
- Select a physical device in the Xcode header and press ▶.
Android
Heads-up: The first build will configure Gradle; it may take a few minutes.
- Run npm start in your system terminal (not the Android Studio terminal).
- Open the android folder in Android Studio and wait for Gradle to build successfully.
- Connect your Android device and enable USB debugging in Developer Options.
- Press ▶ in Android Studio.
Folder Cheat-Sheet
- server.js — Node API (Express)
- .env — Twilio / Firebase credentials - tokens
- /certs — contains an Apple .p8 key (Apple Developer → Keys)
- app.tsx — app entry (starting point)
- /src/assets/Helper/revenueCat.tsx — in-app purchase config - keys (RevenueCat)
- /src/assets/Helper/TwilioApis.js — Twilio APIs (call logs, messages, purchase number, etc.)
- Rest: React Native app files
Common Issues - Fixes
- iOS build fails on first run: run pod install again and re-open .xcworkspace.
- Android device not detected: ensure USB debugging is enabled and run adb devices.
- ENV not loaded: verify .env is present and your env loader is initialized before app start.
VoIP Certificate Generation (iOS)
1) Generate a Private Key
bashopenssl genrsa -out voip_private.key 2048
# Output: voip_private.key
2) Generate a CSR
bashopenssl req -new -key voip_private.key -out voip_csr.csr
# Output: voip_csr.csr
3) Create VoIP Certificate on Apple Developer Portal
- Apple Developer → Certificates → +
- Choose VoIP Services Certificate (Services section)
- Select your Bundle Identifier
- Upload voip_csr.csr → download voip_services.cer
4) Convert .cer
to .pem
bashopenssl x509 -in voip_services.cer -inform DER -out voip_cert.pem -outform PEM
# Output: voip_cert.pem
5) Create a .p12
file
bashopenssl pkcs12 -export \
-inkey voip_private.key \
-in voip_cert.pem \
-out voip_cert.p12 \
-name "VoIP Certificate"
# Output: voip_cert.p12 (set a password)
6) Extract cert.pem
- key.pem
from .p12
bashopenssl pkcs12 -in voip_cert.p12 -clcerts -nokeys -out cert.pem
openssl pkcs12 -in voip_cert.p12 -nocerts -nodes -out key.pem
Result: cert.pem and key.pem are used by Twilio to connect with your app/server.
Upload Keys - Certs in Twilio Console (Push Credentials)
- Twilio Console → API Keys → sidebar Credentials → Push Credentials → +.
- Name it, select APN Push Credentials.
- Open cert.pem and paste into Certificate.
- Open key.pem and paste into Private key.
- Check Sandbox and save.
You’ll get a Credential SID → use as voipPushCredentialSid on the server.
Android FCM Credentials Setup
- Create a Firebase project using your Android package name (e.g., com.yourPackageName.app).
- Go to Service Accounts → create a JSON key → download to project root.
- Open the JSON and copy its contents.
- In Twilio Console → API - Keys → Credentials → create new credentials of type FCM credential.
- Use the resulting Credential SID as fcmPushCredentialSid on the server.
- Open your Notify Service and attach both the APNS credential and the new FCM credential.
You’ll get a SERVICE SID → use as notifyServiceSid on the server.
In-App Products - RevenueCat
Create IAP Products
iOS — App Store Connect
- Open appstoreconnect.apple.com/apps → select your app.
- Side menu → In-App Purchases → +.
- Select type: Consumable (tokens) or Non-Consumable/Subscription as needed.
- Add Name and Product ID → Create.
- On the product page, add storefronts/countries, price, description, and review info.
Android — Play Console
- Open play.google.com → select your app.
- Monetize with Play → In-App Products → Create product (for tokens).
- Enter Product ID, Name, Description, Price → Save → Activate.
- For subscriptions: Monetize with Play → Subscriptions → Create subscription.
- Add Product ID - Name → Create → Add base plan (Pre-Paid), set duration - price → Save → Activate.
Configure RevenueCat
iOS — Keys - Providers
1) Generate an In-App Purchase (IAP) Key
- App Store Connect → Users and Access → Integrations → In-App Purchase → Generate.
- Name the key and download the .p8 file (one-time download). Store it securely.
Note: The IAP .p8 can only be downloaded once.
2) Create an App Store Connect API Key
- App Store Connect → Users and Access → Integrations → App Store Connect API → Generate API Key.
- Assign role Admin and download the .p8 (one-time download). Store it securely.
Note: The API .p8 can only be downloaded once.
3) Connect App Store to RevenueCat
- Go to app.revenuecat.com → Apps - Providers → select App Store.
- Add App Name and Bundle ID (same as in Xcode).
- In-App Purchase key configuration: upload the IAP .p8; enter its Key ID and Issuer ID. You can find it in same page.
- App Store Connect API configuration: upload the API .p8; enter its Key ID and Issuer ID. You can find it in same page.
- Click Save changes.
- Copy the Public API Key (iOS) and paste it into revenueCat.tsx/revenueCat.js.
Android — Service Credentials
- In RevenueCat → Apps - Providers → select Google Play Store → add App Name - Package Name.
- Create a Google Service Account and JSON credentials following RevenueCat’s guide → upload JSON to RevenueCat.
- Click Save changes.
- Copy the Public API Key (Android) and add it to your revenueCat.tsx/js.
Entitlements - Product Catalog
- RevenueCat → Product Catalog → Entitlements → + New Entitlement → add Identifier - Description.
- Open the entitlement → + New → select your app → Import products → choose products → Import.
- Copy the entitlement id (e.g., entl*******) and update it in revenueCat.tsx/js and PlanSelection.js.
- Back in Product Catalog → Products → if empty, Import Products → then Attach each product to your entitlement.
Server API Documentation
The Node server (Express) handles calls, messaging, blocking, and lifecycle operations; integrates Twilio, Firebase, and Socket.IO.
Endpoints (Overview)
Method | Path | Purpose |
---|---|---|
POST | /voice | Initiate outbound call via Twilio |
POST | /voice-handler | Inbound calls, block checks, VoIP push |
POST | /twilio-webhook | Inbound SMS → tokens, FCM push, Socket.IO |
POST | /block | Block a phone number (Twilio Sync) |
POST | /unblock | Unblock a phone number |
GET | /is-blocked | Check if number is blocked |
GET | /blocked | List all blocked numbers |
POST | /delete-user | Delete user - release numbers |
POST | /release-numbers | Release user’s numbers - expire user |
App Functionality - User Flow
Authentication
- User can register with Email, Google, Facebook, or Apple (iOS).
Phone Number Purchase - Subscription
- First-time users must purchase a Twilio number and activate a subscription.
- Once active: make/receive calls, send/receive messages using purchased number.
Multiple Numbers • Billing • Tokens
- Users may buy multiple numbers; each additional number costs 250 tokens.
- Country-wise rates determine per-minute/interval call and per-message costs.
- Tokens are deducted progressively during calls based on the selected country.
Subscription Expiry / Cancellation
- On expiry (or manual cancellation): all purchased numbers are released back to Twilio.
- User token balance is preserved.
- To continue: purchase a new number and reactivate subscription.
Calling
- Enabled only with active subscription, valid number, and sufficient tokens.
- Disabled if subscription expired, tokens = 0, or recipient is blocked.
- Powered by Twilio Voice SDK with background handling.
Messaging
- Real-time via Socket.IO; background notifications for incoming messages.
- Users can block/unblock directly from the chat screen.
Blocking / Unblocking Contacts
- Blocking a number prevents all calls and messages both ways until unblocked.
Access Restrictions
- If subscription expired or tokens are 0 → sending/receiving calls/messages is blocked.
Account Deletion Policy
- Deletes all user data (numbers, messages, call logs, tokens, preferences) irreversibly.