← Back to Blog

Let's be blunt: Backspace.me has never used Firebase. No FCM tokens, no Google Cloud Messaging, no Play Services push. Not in a previous version, not in a test branch, not anywhere. Calls, messages, and wake-ups have always travelled through our own P2P relay nodes — and today we're shipping the piece that makes it airtight: a native keepalive service built from scratch.

Why Almost Everyone Else Uses Firebase

Firebase Cloud Messaging is the default way to wake a mobile app when something arrives. Almost every chat app on Android uses it, because it's the path of least resistance — Google hands you a push pipe, you hand Google your tokens, and the OS happily wakes your app. Easy. Free. Convenient.

It is also, quietly, one of the biggest metadata leaks in modern messaging. Every time a message or call needs to wake your phone, a push goes through Google's servers — and Google logs the who, when, and how often, even if it never sees the payload content.

That is a compromise we were never willing to make. Backspace.me is built on a simple promise: no metadata exists about you anywhere, at any time. Not on our servers. Not on a relay node. Not on Google's. If we shipped a private messenger and Google still knew when you were getting called, the promise would be broken. So we chose the hard path from day one.

The Leak We Refused To Accept

An FCM token is a persistent identifier tied to your device and Google account. Every push through FCM creates a timestamped log entry on Google's infrastructure: token X received a wake-up at time Y. That alone is enough to map call patterns, sleep cycles, and social graphs — without ever decrypting a single message. Backspace will never issue, register, or transmit one of those tokens.

The Firebase Path vs The Backspace Path

Here is the shape of the compromise in one frame. On the left is what almost every other messenger does. On the right is what we do instead — and have always done.

Everyone Else — Firebase

  • FCM token registered with Google
  • Incoming call → server → FCM → device
  • Google logs push timing and recipient
  • Third-party dependency on Play Services
  • Metadata leak by construction

Backspace — Native Keepalive

  • No tokens issued, none to leak
  • Incoming call → node → direct socket → device
  • No third-party sees any event
  • No Google Play Services requirement
  • Metadata does not exist to log

NativeKeepAliveService

The heart of our approach is a small, focused Android foreground service we call NativeKeepAliveService. Its only job is to hold a live connection to the Backspace relay mesh for as long as the app process is allowed to exist — including when the user swipes the app away or taps the home button. No Google involvement at any point.

Inside the service, an OkHttp WebSocket maintains a standby socket to a chosen relay node. It is not a push endpoint. It is not polled. It is a persistent, low-overhead bidirectional pipe that our nodes can write to the instant an event needs to reach you — a call, a priority message, anything else that has to break through the device's doze state.

Why OkHttp

We needed a WebSocket stack that survives network hand-offs, tolerates aggressive battery optimizers, and reconnects fast on flaky carriers. OkHttp is battle-tested in production Android apps at massive scale and gives us control down to ping frames and backoff timing. No third-party SDK, no binary blobs — just a WebSocket client we fully understand, talking only to our own nodes.

Service: NativeKeepAliveService (foreground)
Transport: OkHttp WebSocket, persistent
Endpoint: Backspace relay node (chosen at runtime)
Auth: Ephemeral peer key, no server-side account
Dependencies: None from Google Play Services

Dual-Socket Routing

One WebSocket is not enough when you care about latency. When the app is in the foreground and actively chatting, we already hold a primary socket for message traffic. When the app drops to the background, NativeKeepAliveService brings up a second socket optimized for wake-ups. Both stay healthy at the same time.

Routing between them happens in a tiny function called _findBestSocketForPeer. When a node has something to deliver, it inspects the state of both sockets, picks whichever is currently open and freshest, and writes the event into that one. If both are alive, the primary wins. If the primary is gone — backgrounded, dozing, screen off — the keepalive socket takes the hit. The handover is invisible to the user.

Why Dual Sockets

A single connection is a single point of failure. With two independent sockets on two independent code paths, a backgrounded app can still receive a call in under a second — and a foregrounded app never pays the latency cost of waking the keepalive path. Best of both worlds, zero duplicated delivery.

The Incoming Call Chain

All of this plumbing exists to solve one very hard problem on Android without Firebase: reliably showing a ringing screen when the app is not running. Android's battery optimizers, the Doze mode lifecycle, OEM kill-happy background managers, and the difference between a cold start and a warm resume all conspire to make this genuinely difficult. Firebase exists precisely because most teams give up and hand that problem to Google. We didn't.

Our call chain looks like this:

We tested this across every hostile path we could think of: cold start (app killed by OS), task swipe (user swiped it away from Recents), and home-button background (classic doze path). All three now land on the same answered call. That is the entire point of the build.

Bulletproof Means Bulletproof

We are not claiming zero bugs forever — we are claiming the wake path is deterministic. CallStyle → warm-resume → acceptCall is the only path. There is no Firebase fallback, no Play Services dependency, no silent failure mode that blames Google when the phone doesn't ring. We own the entire chain, end to end.

Zero Metadata, Even On Calls

This is the part that matters to users who don't care about OkHttp or dual-socket routing. In plain English:

What This Means For You

Incoming calls on Backspace arrive through a path that never touches Google. Not once, not as a fallback, not "most of the time". Ever. That means there is no "encrypted chat with a metadata asterisk" situation — it really is zero metadata, including call signaling.

If you are one of the people who runs Backspace specifically because you do not want Google Play Services on your phone: the app works. It works on de-Googled Android. It works on GrapheneOS. It works on any Android with no Play Services at all, because there is nothing in our stack that needs them.

Live In The Current Build

The native keepalive is live right now on the latest Backspace.me build. No server migration, no waiting list, no staged rollout — there was never a Firebase layer to remove in the first place. Every call from day one has taken the native path, and today it's bulletproof across every Android wake scenario we tested.


Private calls, no asterisks

No Google. No Firebase. No metadata. No third-party wake-up tokens. Just encrypted signaling over our own P2P nodes, end to end, from day one.