Turn an Old Android Phone into Your Own SMS Gateway
(Firebase trigger + SENT / DELIVERED tracking – Minimal example)For a long time I was using Firebase Phone Auth to validate access to my app via SMS (OTP).
However, after updating B4A and modernizing parts of the project, I ran into compatibility issues and decided to try something I had been thinking about for a while:
Sometimes we have great ideas but no time to “play” and explore the powerful tools that B4A gives us. This was one of those experiments — and it turned out to be very interesting.
Sample real data collected from MySQL
⚠ Important
This code does NOT work directly by copy & paste.You must configure:
- Firebase Cloud Messaging
- Firebase project
- Manifest entries
- Runtime permissions
The Core Idea
The Android device acts as a “zombie terminal” (in a good way):- It sits there quietly with a SIM card.
- It listens for Firebase Cloud Messaging (FCM).
- When a message arrives, it wakes up.
- It sends a real SMS using SmsManager.
- It captures the delivery status (SENT / FAILED / DELIVERED).
So:
FCM = Trigger
Android SIM = Real SMS sender
No external SMS provider needed.
How It Works – Step by Step
FirebaseMessaging Receiver (the “wake up” trigger)
The device subscribes to a topic (for example "enviarsms").When an FCM message arrives:
- sms_number
- sms_message
- id_sms (your internal DB id)
are extracted from the data payload.
Then:
SendSmsImmutable(id_sms, sms_number, sms_message)
is called.
FCM simply delivers what to send and to whom.
Sending the SMS with SENT / DELIVERED tracking
Inside SendSmsImmutable():
- SmsManager.sendTextMessage() is used.
- Two PendingIntents are created:
- One for SENT
- One for DELIVERED
req → id_sms
This allows us to know exactly which SMS triggered each callback.
smsstatusreceiver (status tracking)
The smsstatusreceiver receives the broadcast events.
It retrieves:
- req
- ev (SENT or DELIVERED)
- GetResultCode
From this it determines:
- SENT (accepted by modem/network)
- DELIVERED (carrier confirmation)
- FAILED (error with code)
This is where you can:
- Update your backend
- Write logs
- Store validation results
Why This Is Interesting
This approach gives you full control and traceability:✔ Know which messages were accepted by the network
✔ Know which were delivered (if supported)
✔ Detect failures and reasons
✔ Maintain your own validation logs
If connected to MySQL (or even a local database), you can build a very robust OTP tracking system.
I’m not explaining SQL or backend connections here because that would make the post too long. The goal is to share the minimal Android “SMS server” concept.
Required Permissions (Critical)
You MUST:
Declare permission in Manifest:
AddPermission(android.permission.SEND_SMS)
Register the receiver:
AddReceiverText(smsstatusreceiver,<intent-filter></intent-filter>)
Request permission at runtime (Android 6+):
rp.CheckAndRequest(rp.PERMISSION_SEND_SMS)
If any of these steps are missing:
- SMS sending will fail
- SENT / DELIVERED callbacks will not work
Runtime permission alone is NOT enough.
Complete Flow Example
- Your backend decides to send an OTP.
- It calls send.php.
- send.php performs:
- Rate limiting
- Phone validation
- Temporary bans if needed
- If valid, send.php sends an FCM message.
- Android device receives FCM.
- Device sends real SMS.
- smsstatusreceiver captures status.
- Backend logs result (via status.php).
- User enters OTP.
- Backend validates via check.php.
My Backend Structure (Concept Only)
I use:
- send.php → validation + send FCM
- status.php → store SMS status in MySQL
- check.php → validate user OTP
I’m not sharing those files because they are quite complex and customized.
The goal of this post is simply to share the minimal Android SMS gateway concept.
Final Thoughts
This setup allows you to:- Avoid external SMS providers
- Use an unlimited SMS SIM
- Fully control validation logic
- Build your own OTP system
It’s not meant to replace professional SMS gateways in production at scale — but for controlled environments or internal systems, it can be very powerful.
I hope someone finds this useful
Best regards.