Skip to main content
All posts
Engineering4 min read

One Tap Should Leave One Ping

A September 2 mobile source fix attaches the server's canonical ID to the sender's immediate feed entry, so one tap does not briefly look like two Pings.

One carved ivory fingertip sends a single Signal Red path through a registration notch to one receiving mark.

One tap should leave one Ping.

A September 2 mobile source fix now attaches the server's canonical ID to the sender's immediate feed entry. The Ping can appear without waiting for a refresh, then reconcile with the stored event instead of briefly becoming a second row.

This describes source code committed after the latest verified mobile builds. It is not proof that the fix is in the public App Store or Google Play release.

A duplicate creates doubt

Imagine tapping Home safe as you close the door.

The Ping appears in the room at once. A moment later, the same event appears again. The unread count moves. Then one copy disappears.

The room may have received only one Ping, but the sender no longer knows that. Was the first row only local? Did the second row reach everyone? Did the sound fire twice?

That uncertainty is the defect. PingRoom is built to remove a checking loop, not create a new one after the tap.

People describe the same loss of confidence when other products duplicate one event. In a recent Google Messages discussion about duplicated sent history, people could not tell whether two visible copies represented one send, a fallback path, or a second action. That thread is evidence of lived frustration, not proof that every duplicate has the same cause.

Immediate feedback still needs an identity

An optimistic interface shows the result of an action before the network finishes. React's useOptimistic documentation describes the pattern plainly: render the temporary value while the action is in progress.

PingRoom needs that speed because the sender does not receive their own push. Waiting for the next rooms refresh would make a Quick Ping feel detached from the tap.

Before this source change, the mobile app inserted a temporary row with a local identity. The successful POST already returned the canonical ID of the notification the server had written, but the dispatcher discarded it. A later refresh tried to match the temporary row to the server row using its fields and a 30-second time window.

That fallback usually worked. It could fail when the send was slow, device and server clocks disagreed, or the debounced refresh never landed. The feed then held two representations of one event: the anonymous local row and the canonical server row.

The response already knows the answer

The new path uses the successful response immediately:

  1. The tap inserts one temporary Ping in the sender's feed.
  2. The server stores the event and returns its canonical notification ID.
  3. The dispatcher stamps that ID onto the existing temporary row.
  4. A refresh matches on exact identity and replaces the representation without remounting it.

A fingertip creates one temporary ivory token; a stone registration press gives it a notch before the same token settles into one final groove.

The field-and-time heuristic remains as a compatibility fallback. It is no longer the first way the app recognizes the event it just sent.

The same response can carry the authoritative acknowledgement state opened by an Urgent Ping. The merge keeps a newer local terminal state if the person has already acknowledged it, so an older response cannot move the event backwards.

Unconfirmed temporary rows also stay out of the cold-start cache. If a send dies with the app, the next launch does not resurrect a Ping that the server may never have received.

One event needs one identity

Mobile platforms use the same underlying idea on their notification surfaces. Android tells developers to reuse the same notification ID when updating an existing notification, and Apple replaces a pending local notification when a new request uses the same notification identifier.

Those APIs do not implement PingRoom's in-room reconciliation. They show why stable identity matters: an update to one event should not look like a second event.

A message is one item in a conversation. A Ping is a state change that can affect unread state, acknowledgement, sound, a Live Activity, and the next action. Showing it twice does more than clutter a feed. It suggests reality changed twice.

What this fix does not claim

This change closes one sender-side identity gap in the mobile source.

It does not guarantee that every external system sends only once. It does not prevent an automation from creating two genuinely separate Pings. It does not resolve operating-system bugs that may display a remote notification twice. Send idempotency, provider delivery, and feed reconciliation remain separate boundaries.

Questions also follow a different confirmation path because their successful response names the Question rather than its backing notification. They reconcile through the canonical Question ID.

The public mobile release has not been verified to contain this September 2 work. Until a later binary is tied to the source commit and checked on physical devices, this remains an implemented and tested source correction.

For the person at the door, the intended result is simple: tap Home safe, see one Ping, and stop wondering whether anyone heard it twice.

PingRoom

The Ping that cuts through.

Keep reading

Product

The Ping With No Words

Quick Pings can now use an emoji as their entire name—a source update for signals that need no caption.

4 min read