Skip to content

Add Set up custom push notifications how-to#5080

Open
shannonbradshaw wants to merge 7 commits into
viamrobotics:mainfrom
shannonbradshaw:shannonbradshaw/custom-push-notifications
Open

Add Set up custom push notifications how-to#5080
shannonbradshaw wants to merge 7 commits into
viamrobotics:mainfrom
shannonbradshaw:shannonbradshaw/custom-push-notifications

Conversation

@shannonbradshaw

@shannonbradshaw shannonbradshaw commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Documents the end-to-end flow for routing trigger push notifications to a custom mobile app instead of the Viam mobile app. Closes the docs follow-up identified during review of #5079.

The new page at docs/monitor/custom-push-notifications.md covers:

  • Firebase service-account JSON upload through viam organizations firebase-config set (with the constraint that it's the Admin SDK service account, not google-services.json / GoogleService-Info.plist).
  • Device-token registration: Flutter SDK wrappers (uploadDevicePushToken / deleteDevicePushToken / getDevicePushTokens) for the one language that has them today, plus raw gRPC notes for Python / TypeScript / Go / C++.
  • The fragment-ownership trust gate: a non-Viam application only delivers if the machine imports a fragment owned by the same organization that uploaded the Firebase config. com.viam.viammobile is exempt by literal name.
  • Trigger config with the application field.
  • Verify / troubleshoot keyed to the actual server-side log messages (trigger push notification failed: app authorization check, recipient is not a robot owner or operator).

Cross-links added from docs/monitor/alert.md, docs/data/trigger-on-data.md, docs/reference/triggers.md, and both the application line and the organizations firebase-config set entry in docs/cli/reference.md.

Review status

Martha reviewed on 2026-05-28 and left three inline suggestions plus answered the design-rationale question. All three suggestions applied in b73e1a407. The rationale question is resolved — leaving the page without a rationale paragraph per Martha's recommendation; her one-sentence answer ("extra layer of security so that only app owners can send push notifications to their app") lives in the PR thread.

Open question for @clintpurser — technical accuracy spot-check

The page makes several claims I want a second pair of eyes on, especially ones that involve client-side or private-repo behavior I cannot fully verify from public source:

  1. Payload data fields (section 5). I list event_type, robot_part_id, machine_name, part_name, app_id based on pushNotificationData() plus pushPayloadData(). Is that the complete and stable set, or are additions expected that third-party app developers should code for defensively?
  2. Recipient "must have accepted push notification permissions." I describe this as a client-side OS permission gate — if the user rejects, no token is registered, no notification is delivered, no server-side error. Is that the right framing, or is there a server-side check I missed?
  3. Fragment-import button label. Section 3 instructs readers to use the configuration-block dialog and click Add fragment. Confirmed in app/ui/src/lib/components/robot/add-resource-menu/create-block-modal/create-block-dialog.svelte:31. Just flagging in case there's an updated UI flow in flight.

A quick "looks right" / "fix N" reply is plenty — no need to write copy.

Test plan

  • Netlify deploy preview renders the new page at /monitor/custom-push-notifications/ with a clean sidebar entry between Set up alerts and Default control interface.
  • All four cross-links resolve in the deploy preview: /monitor/alert/, /data/trigger-on-data/, /reference/triggers/, /cli/reference/.
  • In-page anchor #troubleshoot works; cross-page anchors /cli/reference/#organizations-firebase-config-set, /cli/reference/#login, and /hardware/fragments/#save-your-own-configurations jump correctly.

🤖 Generated with Claude Code

Documents the end-to-end flow for routing trigger push notifications
to a custom mobile app instead of the Viam mobile app: Firebase
service-account upload via `viam organizations firebase-config set`,
device-token registration through the Flutter SDK or raw gRPC, the
fragment-ownership trust gate that authorizes a machine to receive
pushes for a non-Viam app, trigger config with the `application`
field, and a verify/troubleshoot section keyed to the actual server-
side log messages.

Cross-links: docs/monitor/alert.md, docs/data/trigger-on-data.md,
docs/reference/triggers.md, and the application field plus
`organizations firebase-config set` section of docs/cli/reference.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@netlify

netlify Bot commented May 28, 2026

Copy link
Copy Markdown

Deploy Preview for viam-docs ready!

Name Link
🔨 Latest commit b73e1a4
🔍 Latest deploy log https://app.netlify.com/projects/viam-docs/deploys/6a1ec5e36b5e3400089199f5
😎 Deploy Preview https://deploy-preview-5080--viam-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 45 (🟢 up 3 from production)
Accessibility: 100 (no change from production)
Best Practices: 100 (no change from production)
SEO: 92 (no change from production)
PWA: 70 (no change from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@viambot viambot added the safe to build This pull request is marked safe to build from a trusted zone label May 28, 2026
| `device_token` | FCM registration token from `FirebaseMessaging.getToken()`. On iOS, call `getAPNSToken()` first; FCM normalizes both. |
| `device_uuid` | A stable device identifier. Android: `android.id` from `device_info_plus`. iOS: `identifierForVendor`. |

User identity comes from the authenticated Viam session on the call, so there is no `user_id` parameter.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably don't need to call out the lack of a user_id parameter

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped in b73e1a4.

A user can have parallel tokens for `com.viam.viammobile` and a custom app, and only the matching set receives any given push.
- Viam prunes dead tokens automatically when FCM reports "not registered."
No server-side cleanup is required for stale tokens.
- Calling `DeleteDevicePushToken` on logout is still recommended so a shared device does not receive notifications for the previous user.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Calling `DeleteDevicePushToken` on logout is still recommended so a shared device does not receive notifications for the previous user.
- Calling `DeleteDevicePushToken` on logout is still required so a shared device does not receive notifications for the previous user.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied verbatim in b73e1a4 — "recommended" → "required."

Comment on lines +135 to +136
`com.viam.viammobile` is exempt from this check.
Triggers targeting the Viam mobile app work on any machine the recipient owns or operates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be unnecessary since this section is about third party apps

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — dropped both sentences in b73e1a4.

@martha-johnston

Copy link
Copy Markdown
Contributor

overall looks good but I left a couple of suggestions

The page documents what the fragment-ownership trust gate is, but not why the design uses fragment ownership rather than a direct grant API. Two options:

  1. Leave the page as-is (what only); the design rationale isn't load-bearing for someone setting this up.
  2. Add a short rationale paragraph in section 3 ("Authorize the machine") explaining the trust model.

Happy either way — if (2), what's the right one-paragraph explanation?

also, in reference to this question, I don't personally think we need to give a full explanation as to why this is the design. it's just to add an extra layer of security so that only app owners can send push notifications to their app. without this, anyone who knows the bundle id could theoretically send push notifications to an app they don't own

shannonbradshaw and others added 6 commits May 28, 2026 13:20
The "import that fragment" step was vague. Replace with the actual
click sequence the configuration-block dialog uses (`+` →
**Configuration block** → search → **Add fragment**) and link to the
existing fragments how-to for the "create a fragment" half of the
step.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "the Viam mobile app re-uploads if the stored token is older
than 30 days" detail came from internal mobile-app code; it can't
be verified from public source and is implementation detail that
third-party app authors should choose for themselves. Replace with
generic guidance to pick a cadence on app startup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ements

The Required-fields table stated `FirebaseMessaging.getToken()`,
`getAPNSToken()`, `android.id`/`device_info_plus`, and
`identifierForVendor` as if they were Viam requirements. They are
the Viam mobile app's choices and one valid pattern per platform.
Reframe to separate the Viam requirement (an FCM token; a stable
device identifier) from the Viam-mobile-app implementation.

Surfaced by the identifier sweep during the Playbook 1 pass: these
identifiers do not appear in any in-scope public repo and were
sourced to the private viam-mobile repo only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three Missing/Prose findings surfaced by walking the page as a
first-time reader:

- F-WALK-1: Prereqs list mentioned `viam login` but left readers
  staring at `--org-id <your-org-id>` placeholders with no path to
  find their org ID. Added one bullet pointing to app.viam.com and
  `viam organizations list`.
- F-WALK-2: Section 3 implied (correctly) that the fragment's
  owning org must match the Firebase-config-owning org, but did
  not name the cross-org case. Added a one-sentence clarification
  that the check compares the fragment's owner, not the machine's.
- F-WALK-3: Section 5 verify step did not point readers to the
  Troubleshoot table for the "no notification arrived" case. Added
  a one-line pointer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Drop the "no user_id parameter" callout; implementation detail
  irrelevant to a custom-app developer (Martha review comment).
- Change "recommended" to "required" for DeleteDevicePushToken on
  logout. Without it, a shared device continues receiving the prior
  user's notifications (Martha review comment, correctness fix).
- Drop the Viam-mobile-exemption sentences from section 3. This
  page is about custom apps; readers already know they are not
  using com.viam.viammobile (Martha review comment).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shannonbradshaw

Copy link
Copy Markdown
Collaborator Author

@clintpurser would you please review this PR as well. It's large enough that I'd like two sets of eyes on it.

@viamrobotics-overwatch

Copy link
Copy Markdown

Hey @shannonbradshaw — this PR has been approved and CI has been green for 3+ business days. Ready to merge?

Auto-comment from overwatch. Will not re-nudge for 7 days.

@viamrobotics-overwatch

Copy link
Copy Markdown

Hey @shannonbradshaw — this PR has been approved and CI has been green for 8+ business days. Ready to merge?

Auto-comment from overwatch. Will not re-nudge for 7 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to build This pull request is marked safe to build from a trusted zone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants